diff --git a/.gitignore b/.gitignore index b318565f9f..81767f6bfb 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ phpunit.xml composer.lock composer.phar vendor +/report /.settings /.buildpath /.project diff --git a/Classes/PHPWord.php b/Classes/PHPWord.php index d24b9e441b..0614cee094 100755 --- a/Classes/PHPWord.php +++ b/Classes/PHPWord.php @@ -26,12 +26,13 @@ */ /** PHPWORD_BASE_PATH */ +// @codeCoverageIgnoreStart if (!defined('PHPWORD_BASE_PATH')) { define('PHPWORD_BASE_PATH', dirname(__FILE__) . '/'); require PHPWORD_BASE_PATH . 'PHPWord/Autoloader.php'; PHPWord_Autoloader::Register(); } - +// @codeCoverageIgnoreEnd /** * PHPWord @@ -39,6 +40,28 @@ class PHPWord { + /** + * Default font name (Arial) + */ + const DEFAULT_FONT_NAME = 'Arial'; + /** + * Default Font Content Type(default) + * default|eastAsia|cs + */ + const DEFAULT_FONT_CONTENT_TYPE='default'; + /** + * Default font size in points (10pt) + * + * OOXML defined font size values in halfpoints, i.e. twice of what PHPWord + * use, and the conversion will be conducted during XML writing. + */ + const DEFAULT_FONT_SIZE = 10; + + /** + * Default font color (black) + */ + const DEFAULT_FONT_COLOR = '000000'; + /** * Document properties * @@ -74,8 +97,8 @@ class PHPWord public function __construct() { $this->_properties = new PHPWord_DocumentProperties(); - $this->_defaultFontName = 'Arial'; - $this->_defaultFontSize = 20; + $this->_defaultFontName = PHPWord::DEFAULT_FONT_NAME; + $this->_defaultFontSize = PHPWord::DEFAULT_FONT_SIZE; } /** @@ -133,7 +156,7 @@ public function setDefaultFontName($pValue) } /** - * Get default Font size + * Get default Font size (in points) * @return string */ public function getDefaultFontSize() @@ -142,15 +165,24 @@ public function getDefaultFontSize() } /** - * Set default Font size + * Set default Font size (in points) * @param int $pValue */ public function setDefaultFontSize($pValue) { - $pValue = $pValue * 2; $this->_defaultFontSize = $pValue; } + /** + * Set default paragraph style definition to styles.xml + * + * @param array $styles Paragraph style definition + */ + public function setDefaultParagraphStyle($styles) + { + PHPWord_Style::setDefaultParagraphStyle($styles); + } + /** * Adds a paragraph style definition to styles.xml * @@ -215,15 +247,6 @@ public function getSections() return $this->_sectionCollection; } - /** - * Get section count - * @return int - */ - private function _countSections() - { - return count($this->_sectionCollection); - } - /** * Load a Template File * @@ -236,7 +259,18 @@ public function loadTemplate($strFilename) $template = new PHPWord_Template($strFilename); return $template; } else { - trigger_error('Template file ' . $strFilename . ' not found.', E_USER_ERROR); + throw new PHPWord_Exception( + "Template file {$strFilename} not found." + ); } } -} \ No newline at end of file + + /** + * Get section count + * @return int + */ + private function _countSections() + { + return count($this->_sectionCollection); + } +} diff --git a/Classes/PHPWord/Autoloader.php b/Classes/PHPWord/Autoloader.php index 0e7408226d..74d1a50022 100755 --- a/Classes/PHPWord/Autoloader.php +++ b/Classes/PHPWord/Autoloader.php @@ -36,7 +36,7 @@ */ class PHPWord_Autoloader { - const PREFIX = 'PHPWord'; + const PREFIX = 'PhpOffice\PhpWord'; /** * Register the autoloader @@ -82,4 +82,4 @@ public static function autoload($class) } } } -} \ No newline at end of file +} diff --git a/Classes/PHPWord/DocumentProperties.php b/Classes/PHPWord/DocumentProperties.php index 2bf4404319..3fc097b4e0 100755 --- a/Classes/PHPWord/DocumentProperties.php +++ b/Classes/PHPWord/DocumentProperties.php @@ -30,6 +30,13 @@ */ class PHPWord_DocumentProperties { + /** Constants */ + const PROPERTY_TYPE_BOOLEAN = 'b'; + const PROPERTY_TYPE_INTEGER = 'i'; + const PROPERTY_TYPE_FLOAT = 'f'; + const PROPERTY_TYPE_DATE = 'd'; + const PROPERTY_TYPE_STRING = 's'; + const PROPERTY_TYPE_UNKNOWN = 'u'; /** * Creator @@ -101,21 +108,36 @@ class PHPWord_DocumentProperties */ private $_company; + /** + * Manager + * + * @var string + */ + private $_manager; + + /** + * Custom Properties + * + * @var string + */ + private $_customProperties = array(); + /** * Create new PHPWord_DocumentProperties */ public function __construct() { - $this->_creator = ''; + $this->_creator = ''; $this->_lastModifiedBy = $this->_creator; - $this->_created = time(); - $this->_modified = time(); - $this->_title = ''; - $this->_subject = ''; - $this->_description = ''; - $this->_keywords = ''; - $this->_category = ''; - $this->_company = ''; + $this->_created = time(); + $this->_modified = time(); + $this->_title = ''; + $this->_subject = ''; + $this->_description = ''; + $this->_keywords = ''; + $this->_category = ''; + $this->_company = ''; + $this->_manager = ''; } /** @@ -343,4 +365,243 @@ public function setCompany($pValue = '') $this->_company = $pValue; return $this; } -} \ No newline at end of file + + /** + * Get Manager + * + * @return string + */ + public function getManager() + { + return $this->_manager; + } + + /** + * Set Manager + * + * @param string $pValue + * @return PHPExcel_DocumentProperties + */ + public function setManager($pValue = '') + { + $this->_manager = $pValue; + return $this; + } + + /** + * Get a List of Custom Property Names + * + * @return array of string + */ + public function getCustomProperties() + { + return array_keys($this->_customProperties); + } + + /** + * Check if a Custom Property is defined + * + * @param string $propertyName + * @return boolean + */ + public function isCustomPropertySet($propertyName) + { + return isset($this->_customProperties[$propertyName]); + } + + /** + * Get a Custom Property Value + * + * @param string $propertyName + * @return string + */ + public function getCustomPropertyValue($propertyName) + { + if (isset($this->_customProperties[$propertyName])) { + return $this->_customProperties[$propertyName]['value']; + } + + } + + /** + * Get a Custom Property Type + * + * @param string $propertyName + * @return string + */ + public function getCustomPropertyType($propertyName) + { + if (isset($this->_customProperties[$propertyName])) { + return $this->_customProperties[$propertyName]['type']; + } + + } + + /** + * Set a Custom Property + * + * @param string $propertyName + * @param mixed $propertyValue + * @param string $propertyType + * 'i': Integer + * 'f': Floating Point + * 's': String + * 'd': Date/Time + * 'b': Boolean + * @return PHPExcel_DocumentProperties + */ + public function setCustomProperty($propertyName, $propertyValue = '', $propertyType = null) + { + if (($propertyType === null) || (!in_array($propertyType, array( + self::PROPERTY_TYPE_INTEGER, + self::PROPERTY_TYPE_FLOAT, + self::PROPERTY_TYPE_STRING, + self::PROPERTY_TYPE_DATE, + self::PROPERTY_TYPE_BOOLEAN + )))) { + if ($propertyValue === null) { + $propertyType = self::PROPERTY_TYPE_STRING; + } elseif (is_float($propertyValue)) { + $propertyType = self::PROPERTY_TYPE_FLOAT; + } elseif (is_int($propertyValue)) { + $propertyType = self::PROPERTY_TYPE_INTEGER; + } elseif (is_bool($propertyValue)) { + $propertyType = self::PROPERTY_TYPE_BOOLEAN; + } else { + $propertyType = self::PROPERTY_TYPE_STRING; + } + } + + $this->_customProperties[$propertyName] = array( + 'value' => $propertyValue, + 'type' => $propertyType + ); + return $this; + } + + /** + * Convert document propery based on type + * + * @param mixed $propertyValue + * @param string $propertyType + * @return mixed + */ + public static function convertProperty($propertyValue, $propertyType) + { + switch ($propertyType) { + case 'empty': // Empty + return ''; + break; + case 'null': // Null + return null; + break; + case 'i1': // 1-Byte Signed Integer + case 'i2': // 2-Byte Signed Integer + case 'i4': // 4-Byte Signed Integer + case 'i8': // 8-Byte Signed Integer + case 'int': // Integer + return (int) $propertyValue; + break; + case 'ui1': // 1-Byte Unsigned Integer + case 'ui2': // 2-Byte Unsigned Integer + case 'ui4': // 4-Byte Unsigned Integer + case 'ui8': // 8-Byte Unsigned Integer + case 'uint': // Unsigned Integer + return abs((int) $propertyValue); + break; + case 'r4': // 4-Byte Real Number + case 'r8': // 8-Byte Real Number + case 'decimal': // Decimal + return (float) $propertyValue; + break; + case 'lpstr': // LPSTR + case 'lpwstr': // LPWSTR + case 'bstr': // Basic String + return $propertyValue; + break; + case 'date': // Date and Time + case 'filetime': // File Time + return strtotime($propertyValue); + break; + case 'bool': // Boolean + return ($propertyValue == 'true') ? true : false; + break; + case 'cy': // Currency + case 'error': // Error Status Code + case 'vector': // Vector + case 'array': // Array + case 'blob': // Binary Blob + case 'oblob': // Binary Blob Object + case 'stream': // Binary Stream + case 'ostream': // Binary Stream Object + case 'storage': // Binary Storage + case 'ostorage': // Binary Storage Object + case 'vstream': // Binary Versioned Stream + case 'clsid': // Class ID + case 'cf': // Clipboard Data + return $propertyValue; + break; + } + + return $propertyValue; + } + + /** + * Convert document property type + * + * @param string $propertyType + * @return mixed + */ + public static function convertPropertyType($propertyType) + { + switch ($propertyType) { + case 'i1': // 1-Byte Signed Integer + case 'i2': // 2-Byte Signed Integer + case 'i4': // 4-Byte Signed Integer + case 'i8': // 8-Byte Signed Integer + case 'int': // Integer + case 'ui1': // 1-Byte Unsigned Integer + case 'ui2': // 2-Byte Unsigned Integer + case 'ui4': // 4-Byte Unsigned Integer + case 'ui8': // 8-Byte Unsigned Integer + case 'uint': // Unsigned Integer + return self::PROPERTY_TYPE_INTEGER; + break; + case 'r4': // 4-Byte Real Number + case 'r8': // 8-Byte Real Number + case 'decimal': // Decimal + return self::PROPERTY_TYPE_FLOAT; + break; + case 'empty': // Empty + case 'null': // Null + case 'lpstr': // LPSTR + case 'lpwstr': // LPWSTR + case 'bstr': // Basic String + return self::PROPERTY_TYPE_STRING; + break; + case 'date': // Date and Time + case 'filetime': // File Time + return self::PROPERTY_TYPE_DATE; + break; + case 'bool': // Boolean + return self::PROPERTY_TYPE_BOOLEAN; + break; + case 'cy': // Currency + case 'error': // Error Status Code + case 'vector': // Vector + case 'array': // Array + case 'blob': // Binary Blob + case 'oblob': // Binary Blob Object + case 'stream': // Binary Stream + case 'ostream': // Binary Stream Object + case 'storage': // Binary Storage + case 'ostorage': // Binary Storage Object + case 'vstream': // Binary Versioned Stream + case 'clsid': // Class ID + case 'cf': // Clipboard Data + return self::PROPERTY_TYPE_UNKNOWN; + break; + } + return self::PROPERTY_TYPE_UNKNOWN; + } +} diff --git a/Classes/PHPWord/Exception.php b/Classes/PHPWord/Exception.php index bd73d52c7f..91b5d54f22 100755 --- a/Classes/PHPWord/Exception.php +++ b/Classes/PHPWord/Exception.php @@ -46,4 +46,4 @@ public static function errorHandlerCallback($code, $string, $file, $line, $conte $e->file = $file; throw $e; } -} \ No newline at end of file +} diff --git a/Classes/PHPWord/Exceptions/InvalidImageException.php b/Classes/PHPWord/Exceptions/InvalidImageException.php new file mode 100644 index 0000000000..eda84a8d19 --- /dev/null +++ b/Classes/PHPWord/Exceptions/InvalidImageException.php @@ -0,0 +1,15 @@ +getHashIndex(); if (is_null($hashIndex)) { $hashCode = $pSource->getHashCode(); - } else if (isset ($this->_keyMap[$hashIndex])) { + } elseif (isset ($this->_keyMap[$hashIndex])) { $hashCode = $this->_keyMap[$hashIndex]; } else { $hashCode = $pSource->getHashCode(); diff --git a/Classes/PHPWord/IOFactory.php b/Classes/PHPWord/IOFactory.php index a9eae57029..aac0be877c 100755 --- a/Classes/PHPWord/IOFactory.php +++ b/Classes/PHPWord/IOFactory.php @@ -37,7 +37,8 @@ class PHPWord_IOFactory * @var array */ private static $_searchLocations = array( - array('type' => 'IWriter', 'path' => 'PHPWord/Writer/{0}.php', 'class' => 'PHPWord_Writer_{0}') + array('type' => 'IWriter', 'path' => 'PHPWord/Writer/{0}.php', 'class' => 'PHPWord_Writer_{0}'), + array('type' => 'IReader', 'path' => 'PHPWord/Reader/{0}.php', 'class' => 'PHPWord_Reader_{0}' ), ); /** @@ -118,4 +119,40 @@ public static function createWriter(PHPWord $PHPWord, $writerType = '') throw new Exception("No $searchType found for type $writerType"); } + + /** + * Create PHPWord_Reader_IReader + * + * @param string $readerType Example: Word2007 + * @return PHPWord_Reader_IReader + */ + public static function createReader($readerType = '') + { + $searchType = 'IReader'; + + foreach (self::$_searchLocations as $searchLocation) { + if ($searchLocation['type'] == $searchType) { + $className = str_replace('{0}', $readerType, $searchLocation['class']); + + $instance = new $className(); + if ($instance !== null) { + return $instance; + } + } + } + + throw new PHPWord_Exception("No $searchType found for type $readerType"); + } + + /** + * Loads PHPWord from file + * + * @param string $pFilename The name of the file + * @return PHPWord + */ + public static function load($pFilename, $readerType = 'Word2007') + { + $reader = self::createReader($readerType); + return $reader->load($pFilename); + } } diff --git a/Classes/PHPWord/Media.php b/Classes/PHPWord/Media.php index de913719e6..8229413216 100755 --- a/Classes/PHPWord/Media.php +++ b/Classes/PHPWord/Media.php @@ -30,15 +30,16 @@ */ class PHPWord_Media { - /** * Section Media Elements * * @var array */ - private static $_sectionMedia = array('images' => array(), + private static $_sectionMedia = array( + 'images' => array(), 'embeddings' => array(), - 'links' => array()); + 'links' => array() + ); /** * Header Media Elements @@ -61,18 +62,18 @@ class PHPWord_Media */ private static $_objectId = 1325353440; - /** * Add new Section Media Element * * @param string $src * @param string $type + * @param PHPWord_Section_MemoryImage|null $memoryImage * @return mixed */ public static function addSectionMediaElement($src, $type, PHPWord_Section_MemoryImage $memoryImage = null) { $mediaId = md5($src); - $key = ($type == 'image') ? 'images' : 'embeddings'; + $key = ($type === 'image') ? 'images' : 'embeddings'; if (!array_key_exists($mediaId, self::$_sectionMedia[$key])) { $cImg = self::countSectionMediaElements('images'); @@ -81,26 +82,42 @@ public static function addSectionMediaElement($src, $type, PHPWord_Section_Memor $media = array(); - if ($type == 'image') { + $folder = null; + $file = null; + if ($type === 'image') { $cImg++; - $inf = pathinfo($src); - $isMemImage = (substr(strtolower($inf['extension']), 0, 3) == 'php' && $type == 'image') ? true : false; - + //Detect if it's a memory image first by php ext and second by regex + $isMemImage = false; + if (stripos(strrev($src), strrev('.php')) === 0) { + $isMemImage = true; + } + if (!$isMemImage) { + $isMemImage = (filter_var($src, FILTER_VALIDATE_URL) !== false); + } + $extension = ''; if ($isMemImage) { - $ext = $memoryImage->getImageExtension(); + $extension = $memoryImage->getImageExtension(); $media['isMemImage'] = true; $media['createfunction'] = $memoryImage->getImageCreateFunction(); $media['imagefunction'] = $memoryImage->getImageFunction(); } else { - $ext = $inf['extension']; - if ($ext == 'jpeg') { // Office crashes when adding a jpEg Image, so rename to jpg - $ext = 'jpg'; + $imageType = exif_imagetype($src); + if ($imageType === IMAGETYPE_JPEG) { + $extension = 'jpg'; + } elseif ($imageType === IMAGETYPE_GIF) { + $extension = 'gif'; + } elseif ($imageType === IMAGETYPE_PNG) { + $extension = 'png'; + } elseif ($imageType === IMAGETYPE_BMP) { + $extension = 'bmp'; + } elseif ($imageType === IMAGETYPE_TIFF_II || $imageType === IMAGETYPE_TIFF_MM) { + $extension = 'tif'; } } $folder = 'media'; - $file = $type . $cImg . '.' . strtolower($ext); - } elseif ($type == 'oleObject') { + $file = $type . $cImg . '.' . strtolower($extension); + } elseif ($type === 'oleObject') { $cObj++; $folder = 'embedding'; $file = $type . $cObj . '.bin'; @@ -113,27 +130,24 @@ public static function addSectionMediaElement($src, $type, PHPWord_Section_Memor self::$_sectionMedia[$key][$mediaId] = $media; - if ($type == 'oleObject') { + if ($type === 'oleObject') { return array($rID, ++self::$_objectId); - } else { - return $rID; - } - } else { - if ($type == 'oleObject') { - $rID = self::$_sectionMedia[$key][$mediaId]['rID']; - return array($rID, ++self::$_objectId); - } else { - return self::$_sectionMedia[$key][$mediaId]['rID']; } + + return $rID; + } + + if ($type === 'oleObject') { + $rID = self::$_sectionMedia[$key][$mediaId]['rID']; + return array($rID, ++self::$_objectId); } + return self::$_sectionMedia[$key][$mediaId]['rID']; } /** * Add new Section Link Element * * @param string $linkSrc - * @param string $linkName - * * @return mixed */ public static function addSectionLinkElement($linkSrc) @@ -160,12 +174,12 @@ public static function getSectionMediaElements($key = null) { if (!is_null($key)) { return self::$_sectionMedia[$key]; - } else { - $arrImages = self::$_sectionMedia['images']; - $arrObjects = self::$_sectionMedia['embeddings']; - $arrLinks = self::$_sectionMedia['links']; - return array_merge($arrImages, $arrObjects, $arrLinks); } + + $arrImages = self::$_sectionMedia['images']; + $arrObjects = self::$_sectionMedia['embeddings']; + $arrLinks = self::$_sectionMedia['links']; + return array_merge($arrImages, $arrObjects, $arrLinks); } /** @@ -178,12 +192,12 @@ public static function countSectionMediaElements($key = null) { if (!is_null($key)) { return count(self::$_sectionMedia[$key]); - } else { - $cImages = count(self::$_sectionMedia['images']); - $cObjects = count(self::$_sectionMedia['embeddings']); - $cLinks = count(self::$_sectionMedia['links']); - return ($cImages + $cObjects + $cLinks); } + + $cImages = count(self::$_sectionMedia['images']); + $cObjects = count(self::$_sectionMedia['embeddings']); + $cLinks = count(self::$_sectionMedia['links']); + return ($cImages + $cObjects + $cLinks); } /** @@ -191,6 +205,7 @@ public static function countSectionMediaElements($key = null) * * @param int $headerCount * @param string $src + * @param PHPWord_Section_MemoryImage|null $memoryImage * @return int */ public static function addHeaderMediaElement($headerCount, $src, PHPWord_Section_MemoryImage $memoryImage = null) @@ -232,9 +247,8 @@ public static function addHeaderMediaElement($headerCount, $src, PHPWord_Section self::$_headerMedia[$key][$mediaId] = $media; return $rID; - } else { - return self::$_headerMedia[$key][$mediaId]['rID']; } + return self::$_headerMedia[$key][$mediaId]['rID']; } /** @@ -263,6 +277,7 @@ public static function getHeaderMediaElements() * * @param int $footerCount * @param string $src + * @param PHPWord_Section_MemoryImage|null $memoryImage * @return int */ public static function addFooterMediaElement($footerCount, $src, PHPWord_Section_MemoryImage $memoryImage = null) @@ -304,9 +319,8 @@ public static function addFooterMediaElement($footerCount, $src, PHPWord_Section self::$_footerMedia[$key][$mediaId] = $media; return $rID; - } else { - return self::$_footerMedia[$key][$mediaId]['rID']; } + return self::$_footerMedia[$key][$mediaId]['rID']; } /** @@ -330,4 +344,3 @@ public static function getFooterMediaElements() return self::$_footerMedia; } } - diff --git a/Classes/PHPWord/Reader/Abstract.php b/Classes/PHPWord/Reader/Abstract.php new file mode 100644 index 0000000000..18392f8bb8 --- /dev/null +++ b/Classes/PHPWord/Reader/Abstract.php @@ -0,0 +1,107 @@ +readDataOnly; + return true; + } + + /** + * Set read data only + * + * @param boolean $pValue + * @return PHPWord_Reader_IReader + */ + public function setReadDataOnly($pValue = true) + { + $this->readDataOnly = $pValue; + return $this; + } + + /** + * Open file for reading + * + * @param string $pFilename + * @throws PHPWord_Exception + * @return resource + */ + protected function openFile($pFilename) + { + // Check if file exists + if (!file_exists($pFilename) || !is_readable($pFilename)) { + throw new PHPWord_Exception("Could not open " . $pFilename . " for reading! File does not exist."); + } + + // Open file + $this->fileHandle = fopen($pFilename, 'r'); + if ($this->fileHandle === false) { + throw new PHPWord_Exception("Could not open file " . $pFilename . " for reading."); + } + } + + /** + * Can the current PHPWord_Reader_IReader read the file? + * + * @param string $pFilename + * @return boolean + * @throws PHPWord_Exception + */ + public function canRead($pFilename) + { + // Check if file exists + try { + $this->openFile($pFilename); + } catch (Exception $e) { + return false; + } + fclose($this->fileHandle); + return $readable; + } +} diff --git a/Classes/PHPWord/Reader/IReader.php b/Classes/PHPWord/Reader/IReader.php new file mode 100644 index 0000000000..f51eed77bd --- /dev/null +++ b/Classes/PHPWord/Reader/IReader.php @@ -0,0 +1,47 @@ +open($pFilename) === true) { + // check if it is an OOXML archive + $rels = simplexml_load_string($this->getFromZipArchive($zip, "_rels/.rels")); + if ($rels !== false) { + foreach ($rels->Relationship as $rel) { + switch ($rel["Type"]) { + case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument": + if (basename($rel["Target"]) == 'document.xml') { + $return = true; + } + break; + + } + } + } + $zip->close(); + } + + return $return; + } + + /** + * Get from zip archive + * + * @param ZipArchive $archive + * @param string $fileName + * @param bool $removeNamespace + */ + public function getFromZipArchive( + $archive, + $fileName = '', + $removeNamespace = false + ) { + // Root-relative paths + if (strpos($fileName, '//') !== false) { + $fileName = substr($fileName, strpos($fileName, '//') + 1); + } + $fileName = PHPWord_Shared_File::realpath($fileName); + + // Apache POI fixes + $contents = $archive->getFromName($fileName); + if ($contents === false) { + $contents = $archive->getFromName(substr($fileName, 1)); + } + + // Remove namespaces from elements and attributes name + if ($removeNamespace) { + $contents = preg_replace('~(canRead($pFilename)) { + return; + } + + // Initialisations + $word = new PHPWord; + $zip = new ZipArchive; + $zip->open($pFilename); + + // Read properties and documents + $rels = simplexml_load_string($this->getFromZipArchive($zip, "_rels/.rels")); + foreach ($rels->Relationship as $rel) { + switch ($rel["Type"]) { + // Core properties + case "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties": + $xmlCore = simplexml_load_string($this->getFromZipArchive($zip, "{$rel['Target']}")); + if (is_object($xmlCore)) { + $xmlCore->registerXPathNamespace("dc", "http://purl.org/dc/elements/1.1/"); + $xmlCore->registerXPathNamespace("dcterms", "http://purl.org/dc/terms/"); + $xmlCore->registerXPathNamespace("cp", "http://schemas.openxmlformats.org/package/2006/metadata/core-properties"); + $docProps = $word->getProperties(); + $docProps->setCreator((string) self::arrayItem($xmlCore->xpath("dc:creator"))); + $docProps->setLastModifiedBy((string) self::arrayItem($xmlCore->xpath("cp:lastModifiedBy"))); + $docProps->setCreated(strtotime(self::arrayItem($xmlCore->xpath("dcterms:created")))); + $docProps->setModified(strtotime(self::arrayItem($xmlCore->xpath("dcterms:modified")))); + $docProps->setTitle((string) self::arrayItem($xmlCore->xpath("dc:title"))); + $docProps->setDescription((string) self::arrayItem($xmlCore->xpath("dc:description"))); + $docProps->setSubject((string) self::arrayItem($xmlCore->xpath("dc:subject"))); + $docProps->setKeywords((string) self::arrayItem($xmlCore->xpath("cp:keywords"))); + $docProps->setCategory((string) self::arrayItem($xmlCore->xpath("cp:category"))); + } + break; + // Extended properties + case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties": + $xmlCore = simplexml_load_string($this->getFromZipArchive($zip, "{$rel['Target']}")); + if (is_object($xmlCore)) { + $docProps = $word->getProperties(); + if (isset($xmlCore->Company)) { + $docProps->setCompany((string) $xmlCore->Company); + } + if (isset($xmlCore->Manager)) { + $docProps->setManager((string) $xmlCore->Manager); + } + } + break; + // Custom properties + case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties": + $xmlCore = simplexml_load_string($this->getFromZipArchive($zip, "{$rel['Target']}")); + if (is_object($xmlCore)) { + $docProps = $word->getProperties(); + foreach ($xmlCore as $xmlProperty) { + $cellDataOfficeAttributes = $xmlProperty->attributes(); + if (isset($cellDataOfficeAttributes['name'])) { + $propertyName = (string) $cellDataOfficeAttributes['name']; + $cellDataOfficeChildren = $xmlProperty->children("http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"); + $attributeType = $cellDataOfficeChildren->getName(); + $attributeValue = (string) $cellDataOfficeChildren->{$attributeType}; + $attributeValue = PHPWord_DocumentProperties::convertProperty($attributeValue, $attributeType); + $attributeType = PHPWord_DocumentProperties::convertPropertyType($attributeType); + $docProps->setCustomProperty($propertyName, $attributeValue, $attributeType); + } + } + } + break; + // Document + case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument": + $dir = dirname($rel["Target"]); + $archive = "$dir/_rels/" . basename($rel["Target"]) . ".rels"; + $relsDoc = simplexml_load_string($this->getFromZipArchive($zip, $archive)); + $relsDoc->registerXPathNamespace("rel", "http://schemas.openxmlformats.org/package/2006/relationships"); + $xpath = self::arrayItem( + $relsDoc->xpath("rel:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles']") + ); + $xmlDoc = simplexml_load_string($this->getFromZipArchive($zip, "{$rel['Target']}", true)); + if (is_object($xmlDoc)) { + $section = $word->createSection(); + + foreach ($xmlDoc->body->children() as $elm) { + $elmName = $elm->getName(); + if ($elmName == 'p') { // Paragraph/section + // Create new section if section setting found + if ($elm->pPr->sectPr) { + $section->setSettings($this->loadSectionSettings($elm->pPr)); + $section = $word->createSection(); + continue; + } + // Has w:r? It's either text or textrun + if ($elm->r) { + // w:r = 1? It's a plain paragraph + if (count($elm->r) == 1) { + $section->addText( + $elm->r->t, + $this->loadFontStyle($elm->r) + ); + // w:r more than 1? It's a textrun + } else { + $textRun = $section->createTextRun(); + foreach ($elm->r as $r) { + $textRun->addText( + $r->t, + $this->loadFontStyle($r) + ); + } + } + // No, it's a textbreak + } else { + $section->addTextBreak(); + } + } elseif ($elmName == 'sectPr') { + // Last section setting + $section->setSettings($this->loadSectionSettings($xmlDoc->body)); + } + } + } + break; + } + } + + // Read styles + $docRels = simplexml_load_string($this->getFromZipArchive($zip, "word/_rels/document.xml.rels")); + foreach ($docRels->Relationship as $rel) { + switch ($rel["Type"]) { + case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles": + $xmlStyle = simplexml_load_string($this->getFromZipArchive($zip, "word/{$rel['Target']}", true)); + if (is_object($xmlStyle)) { + foreach ($xmlStyle->children() as $elm) { + if ($elm->getName() != 'style') { + continue; + } + $pStyle = null; + $fStyle = null; + $hasParagraphStyle = isset($elm->pPr); + $hasFontStyle = isset($elm->rPr); + $styleName = (string)$elm->name['val']; + if ($hasParagraphStyle) { + $pStyle = $this->loadParagraphStyle($elm); + if (!$hasFontStyle) { + $word->addParagraphStyle($styleName, $pStyle); + } + } + if ($hasFontStyle) { + $fStyle = $this->loadFontStyle($elm); + $word->addFontStyle($styleName, $fStyle, $pStyle); + } + } + } + break; + } + } + $zip->close(); + + return $word; + } + + /** + * Load section settings from SimpleXMLElement + * + * @param SimpleXMLElement $elm + * @return array|string|null + * + * @todo Implement gutter + */ + private function loadSectionSettings($elm) + { + if ($xml = $elm->sectPr) { + $setting = array(); + if ($xml->type) { + $setting['breakType'] = (string)$xml->type['val']; + } + if ($xml->pgSz) { + if (isset($xml->pgSz['w'])) { + $setting['pageSizeW'] = (int)$xml->pgSz['w']; + } + if (isset($xml->pgSz['h'])) { + $setting['pageSizeH'] = (int)$xml->pgSz['h']; + } + if (isset($xml->pgSz['orient'])) { + $setting['orientation'] = (string)$xml->pgSz['orient']; + } + } + if ($xml->pgMar) { + if (isset($xml->pgMar['top'])) { + $setting['topMargin'] = (int)$xml->pgMar['top']; + } + if (isset($xml->pgMar['left'])) { + $setting['leftMargin'] = (int)$xml->pgMar['left']; + } + if (isset($xml->pgMar['bottom'])) { + $setting['bottomMargin'] = (int)$xml->pgMar['bottom']; + } + if (isset($xml->pgMar['right'])) { + $setting['rightMargin'] = (int)$xml->pgMar['right']; + } + if (isset($xml->pgMar['header'])) { + $setting['headerHeight'] = (int)$xml->pgMar['header']; + } + if (isset($xml->pgMar['footer'])) { + $setting['footerHeight'] = (int)$xml->pgMar['footer']; + } + if (isset($xml->pgMar['gutter'])) { + // $setting['gutter'] = (int)$xml->pgMar['gutter']; + } + } + if ($xml->cols) { + if (isset($xml->cols['num'])) { + $setting['colsNum'] = (int)$xml->cols['num']; + } + if (isset($xml->cols['space'])) { + $setting['colsSpace'] = (int)$xml->cols['space']; + } + } + return $setting; + } else { + return null; + } + } + + /** + * Load paragraph style from SimpleXMLElement + * + * @param SimpleXMLElement $elm + * @return array|string|null + */ + private function loadParagraphStyle($elm) + { + if ($xml = $elm->pPr) { + if ($xml->pStyle) { + return (string)$xml->pStyle['val']; + } + $style = array(); + if ($xml->jc) { + $style['align'] = (string)$xml->jc['val']; + } + if ($xml->ind) { + if (isset($xml->ind->left)) { + $style['indent'] = (int)$xml->ind->left; + } + if (isset($xml->ind->hanging)) { + $style['hanging'] = (int)$xml->ind->hanging; + } + if (isset($xml->ind->line)) { + $style['spacing'] = (int)$xml->ind->line; + } + } + if ($xml->spacing) { + if (isset($xml->spacing['after'])) { + $style['spaceAfter'] = (int)$xml->spacing['after']; + } + if (isset($xml->spacing['before'])) { + $style['spaceBefore'] = (int)$xml->spacing['before']; + } + if (isset($xml->spacing['line'])) { + $style['spacing'] = (int)$xml->spacing['line']; + } + } + if ($xml->basedOn) { + $style['basedOn'] = (string)$xml->basedOn['val']; + } + if ($xml->next) { + $style['next'] = (string)$xml->next['val']; + } + if ($xml->widowControl) { + $style['widowControl'] = false; + } + if ($xml->keepNext) { + $style['keepNext'] = true; + } + if ($xml->keepLines) { + $style['keepLines'] = true; + } + if ($xml->pageBreakBefore) { + $style['pageBreakBefore'] = true; + } + return $style; + } else { + return null; + } + } + + /** + * Load font style from SimpleXMLElement + * + * @param SimpleXMLElement $elm + * @return array|string|null + */ + private function loadFontStyle($elm) + { + if ($xml = $elm->rPr) { + if ($xml->rStyle) { + return (string)$xml->rStyle['val']; + } + $style = array(); + if ($xml->rFonts) { + $style['name'] = (string)$xml->rFonts['ascii']; + } + if ($xml->sz) { + $style['size'] = (int)$xml->sz['val'] / 2; + } + if ($xml->color) { + $style['color'] = (string)$xml->color['val']; + } + if ($xml->b) { + $style['bold'] = true; + } + if ($xml->i) { + $style['italic'] = true; + } + if ($xml->u) { + $style['underline'] = (string)$xml->u['val']; + } + if ($xml->strike) { + $style['strikethrough'] = true; + } + if ($xml->highlight) { + $style['fgColor'] = (string)$xml->highlight['val']; + } + if ($xml->vertAlign) { + if ($xml->vertAlign['val'] == 'superscript') { + $style['superScript'] = true; + } else { + $style['subScript'] = true; + } + } + return $style; + } else { + return null; + } + } + + /** + * Get array item + * + * @param array $array + * @param mixed $key + * @return mixed|null + */ + private static function arrayItem($array, $key = 0) + { + return (isset($array[$key]) ? $array[$key] : null); + } +} diff --git a/Classes/PHPWord/Section.php b/Classes/PHPWord/Section.php index aeea422368..95bb9db00c 100755 --- a/Classes/PHPWord/Section.php +++ b/Classes/PHPWord/Section.php @@ -77,7 +77,16 @@ public function __construct($sectionCount, $settings = null) { $this->_sectionCount = $sectionCount; $this->_settings = new PHPWord_Section_Settings(); + $this->setSettings($settings); + } + /** + * Set Section Settings + * + * @param array $settings + */ + public function setSettings($settings = null) + { if (!is_null($settings) && is_array($settings)) { foreach ($settings as $key => $value) { if (substr($key, 0, 1) != '_') { @@ -147,12 +156,14 @@ public function addLink($linkSrc, $linkName = null, $styleFont = null, $stylePar /** * Add a TextBreak Element * - * @param int $count + * @param int $count + * @param null|string|array|PHPWord_Style_Font $fontStyle + * @param null|string|array|PHPWord_Style_Paragraph $paragraphStyle */ - public function addTextBreak($count = 1) + public function addTextBreak($count = 1, $fontStyle = null, $paragraphStyle = null) { for ($i = 1; $i <= $count; $i++) { - $this->_elementCollection[] = new PHPWord_Section_TextBreak(); + $this->_elementCollection[] = new PHPWord_Section_TextBreak($fontStyle, $paragraphStyle); } } @@ -234,7 +245,9 @@ public function addObject($src, $style = null) $this->_elementCollection[] = $object; return $object; } else { - trigger_error('Source does not exist or unsupported object type.'); + throw new PHPWord_Exception( + 'Source does not exist or unsupported object type.' + ); } } @@ -256,7 +269,9 @@ public function addImage($src, $style = null) $this->_elementCollection[] = $image; return $image; } else { - trigger_error('Source does not exist or unsupported image type.'); + throw new PHPWord_Exception( + 'Source does not exist or unsupported image type.' + ); } } @@ -277,7 +292,9 @@ public function addMemoryImage($link, $style = null) $this->_elementCollection[] = $memoryImage; return $memoryImage; } else { - trigger_error('Unsupported image type.'); + throw new PHPWord_Exception( + 'Unsupported image type.' + ); } } @@ -409,4 +426,19 @@ public function getFooter() { return $this->_footer; } -} \ No newline at end of file + + /** + * Create a new Footnote Element + * + * @param string $text + * @return PHPWord_Section_Footnote + */ + public function createFootnote($styleParagraph = null) + { + $footnote = new PHPWord_Section_Footnote($styleParagraph); + $refID = PHPWord_Footnote::addFootnoteElement($footnote); + $footnote->setReferenceId($refID); + $this->_elementCollection[] = $footnote; + return $footnote; + } +} diff --git a/Classes/PHPWord/Section/Footer.php b/Classes/PHPWord/Section/Footer.php index 6e5ae8f7cd..ae2e21194c 100755 --- a/Classes/PHPWord/Section/Footer.php +++ b/Classes/PHPWord/Section/Footer.php @@ -79,14 +79,16 @@ public function addText($text, $styleFont = null, $styleParagraph = null) } /** - * Add a TextBreak Element + * Add TextBreak * - * @param int $count + * @param int $count + * @param null|string|array|PHPWord_Style_Font $fontStyle + * @param null|string|array|PHPWord_Style_Paragraph $paragraphStyle */ - public function addTextBreak($count = 1) + public function addTextBreak($count = 1, $fontStyle = null, $paragraphStyle = null) { for ($i = 1; $i <= $count; $i++) { - $this->_elementCollection[] = new PHPWord_Section_TextBreak(); + $this->_elementCollection[] = new PHPWord_Section_TextBreak($fontStyle, $paragraphStyle); } } @@ -133,7 +135,7 @@ public function addImage($src, $style = null) $this->_elementCollection[] = $image; return $image; } else { - trigger_error('Src does not exist or invalid image type.', E_USER_ERROR); + throw new Exception('Src does not exist or invalid image type.'); } } @@ -154,7 +156,7 @@ public function addMemoryImage($link, $style = null) $this->_elementCollection[] = $memoryImage; return $memoryImage; } else { - trigger_error('Unsupported image type.'); + throw new Exception('Unsupported image type.'); } } @@ -196,6 +198,7 @@ public function setRelationId($rId) /** * Get all Footer Elements + * @return array */ public function getElements() { @@ -209,4 +212,4 @@ public function getFooterCount() { return $this->_footerCount; } -} \ No newline at end of file +} diff --git a/Classes/PHPWord/Section/Footer/PreserveText.php b/Classes/PHPWord/Section/Footer/PreserveText.php index 9ec896c4f6..b162977066 100755 --- a/Classes/PHPWord/Section/Footer/PreserveText.php +++ b/Classes/PHPWord/Section/Footer/PreserveText.php @@ -89,8 +89,10 @@ public function __construct($text = null, $styleFont = null, $styleParagraph = n $this->_styleParagraph = $styleParagraph; } - $pattern = '/({.*?})/'; - $this->_text = preg_split($pattern, $text, null, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); + $matches = preg_split('/({.*?})/', $text, null, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); + if (isset($matches[0])) { + $this->_text = $matches[0]; + } return $this; } diff --git a/Classes/PHPWord/Section/Footnote.php b/Classes/PHPWord/Section/Footnote.php new file mode 100644 index 0000000000..7b2159e46e --- /dev/null +++ b/Classes/PHPWord/Section/Footnote.php @@ -0,0 +1,151 @@ +_elementCollection = array(); + + // Set paragraph style + if (is_array($styleParagraph)) { + $this->_styleParagraph = new PHPWord_Style_Paragraph(); + + foreach ($styleParagraph as $key => $value) { + if (substr($key, 0, 1) != '_') { + $key = '_' . $key; + } + $this->_styleParagraph->setStyleValue($key, $value); + } + } else { + $this->_styleParagraph = $styleParagraph; + } + } + + + /** + * Add a Text Element + * + * @var string $text + * @var mixed $styleFont + * @return PHPWord_Section_Text + */ + public function addText($text = null, $styleFont = null) + { + $givenText = $text; + $text = new PHPWord_Section_Text($givenText, $styleFont); + $this->_elementCollection[] = $text; + return $text; + } + + /** + * Add a Link Element + * + * @param string $linkSrc + * @param string $linkName + * @param mixed $styleFont + * @return PHPWord_Section_Link + */ + public function addLink($linkSrc, $linkName = null, $styleFont = null) + { + + $link = new PHPWord_Section_Link($linkSrc, $linkName, $styleFont); + $rID = PHPWord_Footnote::addFootnoteLinkElement($linkSrc); + $link->setRelationId($rID); + + $this->_elementCollection[] = $link; + return $link; + } + + /** + * Get Footnote content + * + * @return array + */ + public function getElements() + { + return $this->_elementCollection; + } + + /** + * Get Paragraph style + * + * @return PHPWord_Style_Paragraph + */ + public function getParagraphStyle() + { + return $this->_styleParagraph; + } + + /** + * Get Footnote Reference ID + * + * @return int + */ + public function getReferenceId() + { + return $this->_refId; + } + + /** + * Set Footnote Reference ID + * + * @param int $refId + */ + public function setReferenceId($refId) + { + $this->_refId = $refId; + } +} diff --git a/Classes/PHPWord/Section/Header.php b/Classes/PHPWord/Section/Header.php index cb91e0853b..e2f5b2be3d 100755 --- a/Classes/PHPWord/Section/Header.php +++ b/Classes/PHPWord/Section/Header.php @@ -108,14 +108,16 @@ public function addText($text, $styleFont = null, $styleParagraph = null) } /** - * Add a TextBreak Element + * Add TextBreak * - * @param int $count + * @param int $count + * @param null|string|array|PHPWord_Style_Font $fontStyle + * @param null|string|array|PHPWord_Style_Paragraph $paragraphStyle */ - public function addTextBreak($count = 1) + public function addTextBreak($count = 1, $fontStyle = null, $paragraphStyle = null) { for ($i = 1; $i <= $count; $i++) { - $this->_elementCollection[] = new PHPWord_Section_TextBreak(); + $this->_elementCollection[] = new PHPWord_Section_TextBreak($fontStyle, $paragraphStyle); } } @@ -162,7 +164,7 @@ public function addImage($src, $style = null) $this->_elementCollection[] = $image; return $image; } else { - trigger_error('Src does not exist or invalid image type.', E_USER_ERROR); + throw new Exception('Src does not exist or invalid image type.'); } } @@ -183,7 +185,7 @@ public function addMemoryImage($link, $style = null) $this->_elementCollection[] = $memoryImage; return $memoryImage; } else { - trigger_error('Unsupported image type.'); + throw new Exception('Unsupported image type.'); } } @@ -223,7 +225,7 @@ public function addWatermark($src, $style = null) $this->_elementCollection[] = $image; return $image; } else { - trigger_error('Src does not exist or invalid image type.', E_USER_ERROR); + throw new Exception('Src does not exist or invalid image type.'); } } @@ -292,5 +294,4 @@ public function evenPage() { return $this->_type = PHPWord_Section_Header::EVEN; } - -} \ No newline at end of file +} diff --git a/Classes/PHPWord/Section/Image.php b/Classes/PHPWord/Section/Image.php index f4ad628fa9..a8fcde46e8 100755 --- a/Classes/PHPWord/Section/Image.php +++ b/Classes/PHPWord/Section/Image.php @@ -25,12 +25,14 @@ * @version 0.7.0 */ +use PhpOffice\PhpWord\Exceptions\InvalidImageException; +use PhpOffice\PhpWord\Exceptions\UnsupportedImageTypeException; + /** * Class PHPWord_Section_Image */ class PHPWord_Section_Image { - /** * Image Src * @@ -64,42 +66,43 @@ class PHPWord_Section_Image * Create a new Image * * @param string $src - * @param mixed style + * @param mixed $style + * @param bool $isWatermark + * @throws InvalidImageException|UnsupportedImageTypeException */ public function __construct($src, $style = null, $isWatermark = false) { - $_supportedImageTypes = array('jpg', 'jpeg', 'gif', 'png', 'bmp', 'tif', 'tiff'); - - $inf = pathinfo($src); - $ext = strtolower($inf['extension']); - - if (file_exists($src) && in_array($ext, $_supportedImageTypes)) { - $this->_src = $src; - $this->_isWatermark = $isWatermark; - $this->_style = new PHPWord_Style_Image(); - - if (!is_null($style) && is_array($style)) { - foreach ($style as $key => $value) { - if (substr($key, 0, 1) != '_') { - $key = '_' . $key; - } - $this->_style->setStyleValue($key, $value); - } - } + $supportedImageTypes = array(IMAGETYPE_JPEG, IMAGETYPE_GIF, IMAGETYPE_PNG, IMAGETYPE_BMP, IMAGETYPE_TIFF_II, IMAGETYPE_TIFF_MM); - if (isset($style['wrappingStyle'])) { - $this->_style->setWrappingStyle($style['wrappingStyle']); - } + if (!file_exists($src)) { + throw new InvalidImageException; + } - if ($this->_style->getWidth() == null && $this->_style->getHeight() == null) { - $imgData = getimagesize($this->_src); - $this->_style->setWidth($imgData[0]); - $this->_style->setHeight($imgData[1]); + if (!in_array(exif_imagetype($src), $supportedImageTypes)) { + throw new UnsupportedImageTypeException; + } + + $this->_src = $src; + $this->_isWatermark = $isWatermark; + $this->_style = new PHPWord_Style_Image(); + + if (!is_null($style) && is_array($style)) { + foreach ($style as $key => $value) { + if (substr($key, 0, 1) != '_') { + $key = '_' . $key; + } + $this->_style->setStyleValue($key, $value); } + } + + if (isset($style['wrappingStyle'])) { + $this->_style->setWrappingStyle($style['wrappingStyle']); + } - return $this; - } else { - return false; + if ($this->_style->getWidth() == null && $this->_style->getHeight() == null) { + $imgData = getimagesize($this->_src); + $this->_style->setWidth($imgData[0]); + $this->_style->setHeight($imgData[1]); } } @@ -172,4 +175,4 @@ public function setIsWatermark($pValue) { $this->_isWatermark = $pValue; } -} \ No newline at end of file +} diff --git a/Classes/PHPWord/Section/MemoryImage.php b/Classes/PHPWord/Section/MemoryImage.php index 9652955cdc..f1488c4543 100755 --- a/Classes/PHPWord/Section/MemoryImage.php +++ b/Classes/PHPWord/Section/MemoryImage.php @@ -30,7 +30,6 @@ */ class PHPWord_Section_MemoryImage { - /** * Image Src * @@ -85,7 +84,7 @@ class PHPWord_Section_MemoryImage * Create a new Image * * @param string $src - * @param mixed style + * @param mixed $style */ public function __construct($src, $style = null) { @@ -113,10 +112,6 @@ public function __construct($src, $style = null) } $this->_setFunctions(); - - return $this; - } else { - return false; } } @@ -145,7 +140,6 @@ private function _setFunctions() } } - /** * Get Image style * diff --git a/Classes/PHPWord/Section/PageBreak.php b/Classes/PHPWord/Section/PageBreak.php index f7be1cc791..35f8b5c014 100755 --- a/Classes/PHPWord/Section/PageBreak.php +++ b/Classes/PHPWord/Section/PageBreak.php @@ -36,6 +36,5 @@ class PHPWord_Section_PageBreak */ public function __construct() { - // nothing } } diff --git a/Classes/PHPWord/Section/Settings.php b/Classes/PHPWord/Section/Settings.php index 020a82e374..38af6410c5 100755 --- a/Classes/PHPWord/Section/Settings.php +++ b/Classes/PHPWord/Section/Settings.php @@ -150,7 +150,6 @@ class PHPWord_Section_Settings */ private $_borderBottomColor; - /** * Page Numbering Start * @@ -158,6 +157,44 @@ class PHPWord_Section_Settings */ private $pageNumberingStart; + /** + * @var int + */ + private $headerHeight; + + /** + * @var int + */ + private $footerHeight; + + /** + * Section columns count + * + * @var int + */ + private $_colsNum; + + /** + * Section spacing between columns + * + * @var int + */ + private $_colsSpace; + + /** + * Section break type + * + * Options: + * - nextPage: Next page section break + * - nextColumn: Column section break + * - continuous: Continuous section break + * - evenPage: Even page section break + * - oddPage: Odd page section break + * + * @var string + */ + private $_breakType; + /** * Create new Section Settings */ @@ -178,6 +215,11 @@ public function __construct() $this->_borderRightColor = null; $this->_borderBottomSize = null; $this->_borderBottomColor = null; + $this->headerHeight = 720; // set default header and footer to 720 twips (.5 inches) + $this->footerHeight = 720; + $this->_colsNum = 1; + $this->_colsSpace = 720; + $this->_breakType = null; } /** @@ -568,4 +610,121 @@ public function getPageNumberingStart() { return $this->pageNumberingStart; } + + /** + * Get Header Height + * + * @return int + */ + public function getHeaderHeight() + { + return $this->headerHeight; + } + + /** + * Set Header Height + * + * @param int $pValue + */ + public function setHeaderHeight($pValue = '') + { + if (!is_numeric($pValue)) { + $pValue = 720; + } + $this->headerHeight = $pValue; + return $this; + } + + /** + * Get Footer Height + * + * @return int + */ + public function getFooterHeight() + { + return $this->footerHeight; + } + + /** + * Set Footer Height + * + * @param int $pValue + */ + public function setFooterHeight($pValue = '') + { + if (!is_numeric($pValue)) { + $pValue = 720; + } + $this->footerHeight = $pValue; + return $this; + } + + /** + * Set Section Columns Count + * + * @param int $pValue + */ + public function setColsNum($pValue = '') + { + if (!is_numeric($pValue)) { + $pValue = 1; + } + $this->_colsNum = $pValue; + return $this; + } + + /** + * Get Section Columns Count + * + * @return int + */ + public function getColsNum() + { + return $this->_colsNum; + } + + /** + * Set Section Space Between Columns + * + * @param int $pValue + */ + public function setColsSpace($pValue = '') + { + if (!is_numeric($pValue)) { + $pValue = 720; + } + $this->_colsSpace = $pValue; + return $this; + } + + /** + * Get Section Space Between Columns + * + * @return int + */ + public function getColsSpace() + { + return $this->_colsSpace; + } + + /** + * Set Break Type + * + * @param string $pValue + */ + public function setBreakType($pValue = null) + { + $this->_breakType = $pValue; + return $this; + } + + /** + * Get Break Type + * + * @return string + */ + public function getBreakType() + { + return $this->_breakType; + } } diff --git a/Classes/PHPWord/Section/Table.php b/Classes/PHPWord/Section/Table.php index 6d68351a9a..dd93c95ee3 100755 --- a/Classes/PHPWord/Section/Table.php +++ b/Classes/PHPWord/Section/Table.php @@ -45,13 +45,6 @@ class PHPWord_Section_Table */ private $_rows = array(); - /** - * Row heights - * - * @var array - */ - private $_rowHeights = array(); - /** * Table holder * @@ -66,6 +59,13 @@ class PHPWord_Section_Table */ private $_pCount; + /** + * Table width + * + * @var int + */ + private $_width = null; + /** * Create a new table @@ -100,10 +100,11 @@ public function __construct($insideOf, $pCount, $style = null) * * @param int $height */ - public function addRow($height = null) + public function addRow($height = null, $style = null) { - $this->_rows[] = array(); - $this->_rowHeights[] = $height; + $row = new PHPWord_Section_Table_Row($this->_insideOf, $this->_pCount, $height, $style); + $this->_rows[] = $row; + return $row; } /** @@ -113,11 +114,10 @@ public function addRow($height = null) * @param mixed $style * @return PHPWord_Section_Table_Cell */ - public function addCell($width, $style = null) + public function addCell($width = null, $style = null) { - $cell = new PHPWord_Section_Table_Cell($this->_insideOf, $this->_pCount, $width, $style); $i = count($this->_rows) - 1; - $this->_rows[$i][] = $cell; + $cell = $this->_rows[$i]->addCell($width, $style); return $cell; } @@ -132,22 +132,32 @@ public function getRows() } /** - * Get all row heights + * Get table style * - * @return array + * @return PHPWord_Style_Table */ - public function getRowHeights() + public function getStyle() { - return $this->_rowHeights; + return $this->_style; } /** - * Get table style + * Set table width * - * @return PHPWord_Style_Table + * @var int $width */ - public function getStyle() + public function setWidth($width) { - return $this->_style; + $this->_width = $width; + } + + /** + * Get table width + * + * @return int + */ + public function getWidth() + { + return $this->_width; } } diff --git a/Classes/PHPWord/Section/Table/Cell.php b/Classes/PHPWord/Section/Table/Cell.php index b4bc82428a..983f4a2451 100755 --- a/Classes/PHPWord/Section/Table/Cell.php +++ b/Classes/PHPWord/Section/Table/Cell.php @@ -140,19 +140,23 @@ public function addLink($linkSrc, $linkName = null, $style = null) $this->_elementCollection[] = $link; return $link; } else { - trigger_error('Unsupported Link header / footer reference'); + throw new Exception('Unsupported Link header / footer reference'); return false; } } /** - * Add a TextBreak Element + * Add TextBreak * - * @param int $count + * @param int $count + * @param null|string|array|PHPWord_Style_Font $fontStyle + * @param null|string|array|PHPWord_Style_Paragraph $paragraphStyle */ - public function addTextBreak() + public function addTextBreak($count = 1, $fontStyle = null, $paragraphStyle = null) { - $this->_elementCollection[] = new PHPWord_Section_TextBreak(); + for ($i = 1; $i <= $count; $i++) { + $this->_elementCollection[] = new PHPWord_Section_TextBreak($fontStyle, $paragraphStyle); + } } /** @@ -198,7 +202,7 @@ public function addImage($src, $style = null) $this->_elementCollection[] = $image; return $image; } else { - trigger_error('Source does not exist or unsupported image type.'); + throw new Exception('Source does not exist or unsupported image type.'); } } @@ -225,7 +229,7 @@ public function addMemoryImage($link, $style = null) $this->_elementCollection[] = $memoryImage; return $memoryImage; } else { - trigger_error('Unsupported image type.'); + throw new Exception('Unsupported image type.'); } } @@ -266,7 +270,7 @@ public function addObject($src, $style = null) $this->_elementCollection[] = $object; return $object; } else { - trigger_error('Source does not exist or unsupported object type.'); + throw new Exception('Source does not exist or unsupported object type.'); } } @@ -288,7 +292,7 @@ public function addPreserveText($text, $styleFont = null, $styleParagraph = null $this->_elementCollection[] = $ptext; return $ptext; } else { - trigger_error('addPreserveText only supported in footer/header.'); + throw new Exception('addPreserveText only supported in footer/header.'); } } @@ -333,4 +337,4 @@ public function getWidth() { return $this->_width; } -} \ No newline at end of file +} diff --git a/Classes/PHPWord/Section/Table/Row.php b/Classes/PHPWord/Section/Table/Row.php new file mode 100644 index 0000000000..d174ef8f46 --- /dev/null +++ b/Classes/PHPWord/Section/Table/Row.php @@ -0,0 +1,141 @@ +_insideOf = $insideOf; + $this->_pCount = $pCount; + $this->_height = $height; + $this->_style = new PHPWord_Style_Row(); + + if (!is_null($style)) { + if (is_array($style)) { + + foreach ($style as $key => $value) { + if (substr($key, 0, 1) != '_') { + $key = '_' . $key; + } + $this->_style->setStyleValue($key, $value); + } + } + } + } + + /** + * Add a cell + * + * @param int $width + * @param mixed $style + * @return PHPWord_Section_Table_Cell + */ + public function addCell($width = null, $style = null) + { + $cell = new PHPWord_Section_Table_Cell($this->_insideOf, $this->_pCount, $width, $style); + $this->_cells[] = $cell; + return $cell; + } + + /** + * Get all cells + * + * @return array + */ + public function getCells() + { + return $this->_cells; + } + + /** + * Get row style + * + * @return PHPWord_Style_Row + */ + public function getStyle() + { + return $this->_style; + } + + /** + * Get row height + * + * @return int + */ + public function getHeight() + { + return $this->_height; + } +} diff --git a/Classes/PHPWord/Section/Text.php b/Classes/PHPWord/Section/Text.php index 2b37e7d401..296084e648 100755 --- a/Classes/PHPWord/Section/Text.php +++ b/Classes/PHPWord/Section/Text.php @@ -30,46 +30,63 @@ */ class PHPWord_Section_Text { - /** * Text content * * @var string */ - private $_text; + private $text; /** * Text style * * @var PHPWord_Style_Font */ - private $_styleFont; + private $fontStyle; /** * Paragraph style * - * @var PHPWord_Style_Font + * @var PHPWord_Style_Paragraph */ - private $_styleParagraph; - + private $paragraphStyle; /** * Create a new Text Element * - * @var string $text - * @var mixed $style + * @param string $text + * @param null|array|\PHPWord_Style_Font $fontStyle + * @param null|array|\PHPWord_Style_Paragraph $paragraphStyle */ - public function __construct($text = null, $styleFont = null, $styleParagraph = null) + public function __construct($text = null, $fontStyle = null, $paragraphStyle = null) { - // Set font style - $this->setFontStyle($styleFont); - - // Set paragraph style - $this->setParagraphStyle($styleParagraph); - - $this->_text = $text; + $this->setText($text); + $paragraphStyle = $this->setParagraphStyle($paragraphStyle); + $this->setFontStyle($fontStyle, $paragraphStyle); + } - return $this; + /** + * Set Text style + * + * @param null|array|\PHPWord_Style_Font $style + * @param null|array|\PHPWord_Style_Paragraph $paragraphStyle + * @return PHPWord_Style_Font + */ + public function setFontStyle($style = null, $paragraphStyle = null) + { + if ($style instanceof PHPWord_Style_Font) { + $this->fontStyle = $style; + $this->setParagraphStyle($paragraphStyle); + } elseif (is_array($style)) { + $this->fontStyle = new PHPWord_Style_Font('text', $paragraphStyle); + $this->fontStyle->setArrayStyle($style); + } elseif (null === $style) { + $this->fontStyle = new PHPWord_Style_Font('text', $paragraphStyle); + } else { + $this->fontStyle = $style; + $this->setParagraphStyle($paragraphStyle); + } + return $this->fontStyle; } /** @@ -79,28 +96,28 @@ public function __construct($text = null, $styleFont = null, $styleParagraph = n */ public function getFontStyle() { - return $this->_styleFont; + return $this->fontStyle; } /** - * Set Text style + * Set Paragraph style * - * @return PHPWord_Style_Font + * @param null|array|\PHPWord_Style_Paragraph $style + * @return null|\PHPWord_Style_Paragraph */ - public function setFontStyle($styleFont) + public function setParagraphStyle($style = null) { - if (is_array($styleFont)) { - $this->_styleFont = new PHPWord_Style_Font('text'); - - foreach ($styleFont as $key => $value) { - if (substr($key, 0, 1) != '_') { - $key = '_' . $key; - } - $this->_styleFont->setStyleValue($key, $value); - } + if (is_array($style)) { + $this->paragraphStyle = new PHPWord_Style_Paragraph; + $this->paragraphStyle->setArrayStyle($style); + } elseif ($style instanceof PHPWord_Style_Paragraph) { + $this->paragraphStyle = $style; + } elseif (null === $style) { + $this->paragraphStyle = new PHPWord_Style_Paragraph; } else { - $this->_styleFont = $styleFont; + $this->paragraphStyle = $style; } + return $this->paragraphStyle; } /** @@ -110,28 +127,17 @@ public function setFontStyle($styleFont) */ public function getParagraphStyle() { - return $this->_styleParagraph; + return $this->paragraphStyle; } /** - * Set Paragraph style - * - * @return PHPWord_Style_Paragraph + * @param string $text + * @return $this */ - public function setParagraphStyle($styleParagraph) + public function setText($text) { - if (is_array($styleParagraph)) { - $this->_styleParagraph = new PHPWord_Style_Paragraph(); - - foreach ($styleParagraph as $key => $value) { - if (substr($key, 0, 1) != '_') { - $key = '_' . $key; - } - $this->_styleParagraph->setStyleValue($key, $value); - } - } else { - $this->_styleParagraph = $styleParagraph; - } + $this->text = $text; + return $this; } /** @@ -141,6 +147,6 @@ public function setParagraphStyle($styleParagraph) */ public function getText() { - return $this->_text; + return $this->text; } } diff --git a/Classes/PHPWord/Section/TextBreak.php b/Classes/PHPWord/Section/TextBreak.php index 173672ecfc..0438bd4fc7 100755 --- a/Classes/PHPWord/Section/TextBreak.php +++ b/Classes/PHPWord/Section/TextBreak.php @@ -30,12 +30,91 @@ */ class PHPWord_Section_TextBreak { + /** + * Paragraph style + * + * @var PHPWord_Style_Pagaraph + */ + private $paragraphStyle = null; + + /** + * Text style + * + * @var PHPWord_Style_Font + */ + private $fontStyle = null; /** * Create a new TextBreak Element */ - public function __construct() + public function __construct($fontStyle = null, $paragraphStyle = null) + { + if (!is_null($paragraphStyle)) { + $paragraphStyle = $this->setParagraphStyle($paragraphStyle); + } + if (!is_null($fontStyle)) { + $this->setFontStyle($fontStyle, $paragraphStyle); + } + } + + /** + * Set Text style + * + * @param null|array|\PHPWord_Style_Font $style + * @param null|array|\PHPWord_Style_Paragraph $paragraphStyle + * @return PHPWord_Style_Font + */ + public function setFontStyle($style = null, $paragraphStyle = null) + { + if ($style instanceof PHPWord_Style_Font) { + $this->fontStyle = $style; + $this->setParagraphStyle($paragraphStyle); + } elseif (is_array($style)) { + $this->fontStyle = new PHPWord_Style_Font('text', $paragraphStyle); + $this->fontStyle->setArrayStyle($style); + } else { + $this->fontStyle = $style; + $this->setParagraphStyle($paragraphStyle); + } + return $this->fontStyle; + } + + /** + * Get Text style + * + * @return PHPWord_Style_Font + */ + public function getFontStyle() + { + return $this->fontStyle; + } + + /** + * Set Paragraph style + * + * @param null|array|\PHPWord_Style_Paragraph $style + * @return null|\PHPWord_Style_Paragraph + */ + public function setParagraphStyle($style = null) + { + if (is_array($style)) { + $this->paragraphStyle = new PHPWord_Style_Paragraph; + $this->paragraphStyle->setArrayStyle($style); + } elseif ($style instanceof PHPWord_Style_Paragraph) { + $this->paragraphStyle = $style; + } else { + $this->paragraphStyle = $style; + } + return $this->paragraphStyle; + } + + /** + * Get Paragraph style + * + * @return PHPWord_Style_Paragraph + */ + public function getParagraphStyle() { - // nothing + return $this->paragraphStyle; } } diff --git a/Classes/PHPWord/Section/TextRun.php b/Classes/PHPWord/Section/TextRun.php index a9104341d3..a708a1197f 100755 --- a/Classes/PHPWord/Section/TextRun.php +++ b/Classes/PHPWord/Section/TextRun.php @@ -109,6 +109,57 @@ public function addLink($linkSrc, $linkName = null, $styleFont = null) return $link; } + /** + * Add a Image Element + * + * @param string $imageSrc + * @param mixed $styleFont + * @return PHPWord_Section_Image + */ + public function addImage($imageSrc, $style = null) + { + $image = new PHPWord_Section_Image($imageSrc, $style); + + if (!is_null($image->getSource())) { + $rID = PHPWord_Media::addSectionMediaElement($imageSrc, 'image'); + $image->setRelationId($rID); + + $this->_elementCollection[] = $image; + return $image; + } else { + throw new Exception('Source does not exist or unsupported image type.'); + } + } + + /** + * Add TextBreak + * + * @param int $count + * @param null|string|array|PHPWord_Style_Font $fontStyle + * @param null|string|array|PHPWord_Style_Paragraph $paragraphStyle + */ + public function addTextBreak($count = 1, $fontStyle = null, $paragraphStyle = null) + { + for ($i = 1; $i <= $count; $i++) { + $this->_elementCollection[] = new PHPWord_Section_TextBreak($fontStyle, $paragraphStyle); + } + } + + /** + * Create a new Footnote Element + * + * @param string $text + * @return PHPWord_Section_Footnote + */ + public function createFootnote($styleParagraph = null) + { + $footnote = new PHPWord_Section_Footnote($styleParagraph); + $refID = PHPWord_Footnote::addFootnoteElement($footnote); + $footnote->setReferenceId($refID); + $this->_elementCollection[] = $footnote; + return $footnote; + } + /** * Get TextRun content * @@ -128,4 +179,4 @@ public function getParagraphStyle() { return $this->_styleParagraph; } -} \ No newline at end of file +} diff --git a/Classes/PHPWord/Settings.php b/Classes/PHPWord/Settings.php new file mode 100644 index 0000000000..af400551c3 --- /dev/null +++ b/Classes/PHPWord/Settings.php @@ -0,0 +1,65 @@ +open($zipFile) === true) { - $returnValue = ($zip->getFromName($archiveFile) !== false); - $zip->close(); - return $returnValue; - } else { - return false; - } - } else { - // Regular file_exists - return file_exists($pFilename); - } + // Regular file_exists + return file_exists($pFilename); } /** @@ -76,7 +58,7 @@ public static function realpath($pFilename) // Found something? if ($returnValue == '' || is_null($returnValue)) { - $pathArray = split('/', $pFilename); + $pathArray = explode('/', $pFilename); while (in_array('..', $pathArray) && $pathArray[0] != '..') { for ($i = 0; $i < count($pathArray); ++$i) { if ($pathArray[$i] == '..' && $i > 0) { diff --git a/Classes/PHPWord/Shared/Font.php b/Classes/PHPWord/Shared/Font.php index be3cf1a8b6..9e6dc44f9f 100755 --- a/Classes/PHPWord/Shared/Font.php +++ b/Classes/PHPWord/Shared/Font.php @@ -77,4 +77,15 @@ public static function pixelSizeToTwips($sizeInPixel = 1) { return self::centimeterSizeToTwips($sizeInPixel / 37.795275591); } + + /** + * Calculate twip based on point size, used mainly for paragraph spacing + * + * @param int|float $sizeInPoint Size in point + * @return int|float Size (in twips) + */ + public static function pointSizeToTwips($sizeInPoint = 1) + { + return ($sizeInPoint * 20); + } } diff --git a/Classes/PHPWord/Shared/String.php b/Classes/PHPWord/Shared/String.php index f570e6b7b9..64abdf1d8d 100755 --- a/Classes/PHPWord/Shared/String.php +++ b/Classes/PHPWord/Shared/String.php @@ -37,20 +37,6 @@ class PHPWord_Shared_String */ private static $_controlCharacters = array(); - /** - * Is mbstring extension avalable? - * - * @var boolean - */ - private static $_isMbstringEnabled; - - /** - * Is iconv extension avalable? - * - * @var boolean - */ - private static $_isIconvEnabled; - /** * Build control characters array */ @@ -65,40 +51,6 @@ private static function _buildControlCharacters() } } - /** - * Get whether mbstring extension is available - * - * @return boolean - */ - public static function getIsMbstringEnabled() - { - if (isset(self::$_isMbstringEnabled)) { - return self::$_isMbstringEnabled; - } - - self::$_isMbstringEnabled = function_exists('mb_convert_encoding') ? - true : false; - - return self::$_isMbstringEnabled; - } - - /** - * Get whether iconv extension is available - * - * @return boolean - */ - public static function getIsIconvEnabled() - { - if (isset(self::$_isIconvEnabled)) { - return self::$_isIconvEnabled; - } - - self::$_isIconvEnabled = function_exists('iconv') ? - true : false; - - return self::$_isIconvEnabled; - } - /** * Convert from OpenXML escaped control character to PHP control character * @@ -155,116 +107,4 @@ public static function IsUTF8($value = '') { return $value === '' || preg_match('/^./su', $value) === 1; } - - /** - * Formats a numeric value as a string for output in various output writers - * - * @param mixed $value - * @return string - */ - public static function FormatNumber($value) - { - return number_format($value, 2, '.', ''); - } - - /** - * Converts a UTF-8 string into BIFF8 Unicode string data (8-bit string length) - * Writes the string using uncompressed notation, no rich text, no Asian phonetics - * If mbstring extension is not available, ASCII is assumed, and compressed notation is used - * although this will give wrong results for non-ASCII strings - * see OpenOffice.org's Documentation of the Microsoft Excel File Format, sect. 2.5.3 - * - * @param string $value UTF-8 encoded string - * @return string - */ - public static function UTF8toBIFF8UnicodeShort($value) - { - // character count - $ln = self::CountCharacters($value, 'UTF-8'); - - // option flags - $opt = (self::getIsMbstringEnabled() || self::getIsIconvEnabled()) ? - 0x0001 : 0x0000; - - // characters - $chars = self::ConvertEncoding($value, 'UTF-16LE', 'UTF-8'); - - $data = pack('CC', $ln, $opt) . $chars; - return $data; - } - - /** - * Converts a UTF-8 string into BIFF8 Unicode string data (16-bit string length) - * Writes the string using uncompressed notation, no rich text, no Asian phonetics - * If mbstring extension is not available, ASCII is assumed, and compressed notation is used - * although this will give wrong results for non-ASCII strings - * see OpenOffice.org's Documentation of the Microsoft Excel File Format, sect. 2.5.3 - * - * @param string $value UTF-8 encoded string - * @return string - */ - public static function UTF8toBIFF8UnicodeLong($value) - { - // character count - $ln = self::CountCharacters($value, 'UTF-8'); - - // option flags - $opt = (self::getIsMbstringEnabled() || self::getIsIconvEnabled()) ? - 0x0001 : 0x0000; - - // characters - $chars = self::ConvertEncoding($value, 'UTF-16LE', 'UTF-8'); - - $data = pack('vC', $ln, $opt) . $chars; - return $data; - } - - /** - * Convert string from one encoding to another. First try mbstring, then iconv, or no convertion - * - * @param string $value - * @param string $to Encoding to convert to, e.g. 'UTF-8' - * @param string $from Encoding to convert from, e.g. 'UTF-16LE' - * @return string - */ - public static function ConvertEncoding($value, $to, $from) - { - if (self::getIsMbstringEnabled()) { - $value = mb_convert_encoding($value, $to, $from); - return $value; - } - - if (self::getIsIconvEnabled()) { - $value = iconv($from, $to, $value); - return $value; - } - - // else, no conversion - return $value; - } - - /** - * Get character count. First try mbstring, then iconv, finally strlen - * - * @param string $value - * @param string $enc Encoding - * @return int Character count - */ - public static function CountCharacters($value, $enc = 'UTF-8') - { - if (self::getIsMbstringEnabled()) { - $count = mb_strlen($value, $enc); - return $count; - } - - if (self::getIsIconvEnabled()) { - $count = iconv_strlen($value, $enc); - return $count; - } - - // else strlen - $count = strlen($value); - return $count; - } - } diff --git a/Classes/PHPWord/Shared/XMLWriter.php b/Classes/PHPWord/Shared/XMLWriter.php index 2795083eac..91a9d53079 100755 --- a/Classes/PHPWord/Shared/XMLWriter.php +++ b/Classes/PHPWord/Shared/XMLWriter.php @@ -57,7 +57,7 @@ class PHPWord_Shared_XMLWriter private $_tempFileName = ''; /** - * Create a new PHPPowerPoint_Shared_XMLWriter instance + * Create a new PHPWord_Shared_XMLWriter instance * * @param int $pTemporaryStorage Temporary storage location * @param string $pTemporaryStorageFolder Temporary storage folder @@ -81,15 +81,15 @@ public function __construct($pTemporaryStorage = self::STORAGE_MEMORY, $pTempora } } - // Set default values - // proposed to be false in production version - $this->_xmlWriter->setIndent(true); - //$this->_xmlWriter->setIndent(false); - - // Set indent - // proposed to be '' in production version - $this->_xmlWriter->setIndentString(' '); - //$this->_xmlWriter->setIndentString(''); + // Set xml Compatibility + $compatibility = PHPWord_Settings::getCompatibility(); + if ($compatibility) { + $this->_xmlWriter->setIndent(false); + $this->_xmlWriter->setIndentString(''); + } else { + $this->_xmlWriter->setIndent(true); + $this->_xmlWriter->setIndentString(' '); + } } /** @@ -150,4 +150,4 @@ public function writeRaw($text) return $this->text($text); } -} \ No newline at end of file +} diff --git a/Classes/PHPWord/Shared/ZipStreamWrapper.php b/Classes/PHPWord/Shared/ZipStreamWrapper.php index 0dc4287591..bfdc791b17 100755 --- a/Classes/PHPWord/Shared/ZipStreamWrapper.php +++ b/Classes/PHPWord/Shared/ZipStreamWrapper.php @@ -25,11 +25,10 @@ * @version 0.7.0 */ -/** Register new zip wrapper */ -PHPWord_Shared_ZipStreamWrapper::register(); - /** * Class PHPWord_Shared_ZipStreamWrapper + * + * @codeCoverageIgnore Legacy from PHPExcel */ class PHPWord_Shared_ZipStreamWrapper { @@ -121,7 +120,7 @@ public function stream_stat() /** * Read stream */ - function stream_read($count) + public function stream_read($count) { $ret = substr($this->_data, $this->_position, $count); $this->_position += strlen($ret); diff --git a/Classes/PHPWord/Style.php b/Classes/PHPWord/Style.php index 7b20f8ab07..060ce1be73 100755 --- a/Classes/PHPWord/Style.php +++ b/Classes/PHPWord/Style.php @@ -140,6 +140,16 @@ public static function addTitleStyle($titleCount, $styleFont, $styleParagraph = } } + /** + * Set default paragraph style + * + * @param array $styles Paragraph style definition + */ + public static function setDefaultParagraphStyle($styles) + { + self::addParagraphStyle('Normal', $styles); + } + /** * Get all styles * @@ -165,4 +175,3 @@ public static function getStyle($styleName) } } } - diff --git a/Classes/PHPWord/Style/Cell.php b/Classes/PHPWord/Style/Cell.php index e7d2bf9125..10d4a9be23 100755 --- a/Classes/PHPWord/Style/Cell.php +++ b/Classes/PHPWord/Style/Cell.php @@ -35,7 +35,7 @@ class PHPWord_Style_Cell const TEXT_DIR_TBRL = 'tbRl'; /** - * Vertical align + * Vertical align (top, center, both, bottom) * * @var string */ @@ -123,14 +123,17 @@ class PHPWord_Style_Cell * * @var integer */ - private $_gridSpan = NULL; + private $_gridSpan = null; /** - * rowspan + * rowspan (restart, continue) * - * @var integer + * - restart: Start/restart merged region + * - continue: Continue merged region + * + * @var string */ - private $_vMerge = NULL; + private $_vMerge = null; /** * Create a new Cell Style @@ -198,11 +201,6 @@ public function setBgColor($pValue = null) $this->_bgColor = $pValue; } - public function setHeight($pValue = null) - { - $this->_height = $pValue; - } - public function setBorderSize($pValue = null) { $this->_borderTopSize = $pValue; @@ -344,4 +342,4 @@ public function getVMerge() { return $this->_vMerge; } -} \ No newline at end of file +} diff --git a/Classes/PHPWord/Style/Font.php b/Classes/PHPWord/Style/Font.php index e273dd35da..bc5ee511e8 100755 --- a/Classes/PHPWord/Style/Font.php +++ b/Classes/PHPWord/Style/Font.php @@ -1,4 +1,5 @@ _type = $type; - $this->_name = 'Arial'; - $this->_size = 20; - $this->_bold = false; - $this->_italic = false; - $this->_superScript = false; - $this->_subScript = false; - $this->_underline = PHPWord_Style_Font::UNDERLINE_NONE; - $this->_strikethrough = false; - $this->_color = '000000'; - $this->_fgColor = null; - - if (!is_null($styleParagraph)) { - $paragraph = new PHPWord_Style_Paragraph(); - foreach ($styleParagraph as $key => $value) { - if (substr($key, 0, 1) != '_') { - $key = '_' . $key; - } - $paragraph->setStyleValue($key, $value); - } - $this->_paragraphStyle = $paragraph; + + if ($paragraphStyle instanceof PHPWord_Style_Paragraph) { + $this->_paragraphStyle = $paragraphStyle; + } elseif (is_array($paragraphStyle)) { + $this->_paragraphStyle = new PHPWord_Style_Paragraph; + $this->_paragraphStyle->setArrayStyle($paragraphStyle); } else { - $this->_paragraphStyle = null; + $this->_paragraphStyle = $paragraphStyle; } } - public function getName() + /** + * @param array $style + * @return $this + */ + public function setArrayStyle(array $style = array()) { - return $this->_name; + foreach ($style as $key => $value) { + if ($key === 'line-height') { + $this->setLineHeight($value); + null; + } elseif (substr($key, 0, 1) !== '_') { + $key = '_' . $key; + } + $this->setStyleValue($key, $value); + } + + return $this; } + /** + * Set style value + * + * @param string $key + * @param mixed $value + */ public function setStyleValue($key, $value) { - if ($key == '_size') { - $value *= 2; + $method = 'set' . substr($key, 1); + if (method_exists($this, $method)) { + $this->$method($value); } - $this->$key = $value; } - public function setName($pValue = 'Arial') + /** + * Get font name + * + * @return bool + */ + public function getName() { - if ($pValue == '') { - $pValue = 'Arial'; + return $this->_name; + } + + /** + * Set font name + * + * @param string $pValue + * @return PHPWord_Style_Font + */ + public function setName($pValue = PHPWord::DEFAULT_FONT_NAME) + { + if (is_null($pValue) || $pValue == '') { + $pValue = PHPWord::DEFAULT_FONT_NAME; } $this->_name = $pValue; return $this; } + + /** + * Get font size + * + * @return int|float + */ public function getSize() { return $this->_size; } - public function setSize($pValue = 20) + /** + * Set font size + * + * @param int|float $pValue + * @return PHPWord_Style_Font + */ + public function setSize($pValue = PHPWord::DEFAULT_FONT_SIZE) { - if ($pValue == '') { - $pValue = 20; + if (!is_numeric($pValue)) { + $pValue = PHPWord::DEFAULT_FONT_SIZE; } - $this->_size = ($pValue * 2); + $this->_size = $pValue; return $this; } + /** + * Get bold + * + * @return bool + */ public function getBold() { return $this->_bold; } + /** + * Set bold + * + * @param bool $pValue + * @return PHPWord_Style_Font + */ public function setBold($pValue = false) { - if ($pValue == '') { + if (!is_bool($pValue)) { $pValue = false; } $this->_bold = $pValue; return $this; } + /** + * Get italics + * + * @return bool + */ public function getItalic() { return $this->_italic; } + /** + * Set italics + * + * @param bool $pValue + * @return PHPWord_Style_Font + */ public function setItalic($pValue = false) { - if ($pValue == '') { + if (!is_bool($pValue)) { $pValue = false; } $this->_italic = $pValue; return $this; } + /** + * Get superscript + * + * @return bool + */ public function getSuperScript() { return $this->_superScript; } + /** + * Set superscript + * + * @param bool $pValue + * @return PHPWord_Style_Font + */ public function setSuperScript($pValue = false) { - if ($pValue == '') { + if (!is_bool($pValue)) { $pValue = false; } $this->_superScript = $pValue; @@ -198,14 +344,25 @@ public function setSuperScript($pValue = false) return $this; } + /** + * Get superscript + * + * @return bool + */ public function getSubScript() { return $this->_subScript; } + /** + * Set subscript + * + * @param bool $pValue + * @return PHPWord_Style_Font + */ public function setSubScript($pValue = false) { - if ($pValue == '') { + if (!is_bool($pValue)) { $pValue = false; } $this->_subScript = $pValue; @@ -213,11 +370,22 @@ public function setSubScript($pValue = false) return $this; } + /** + * Get underline + * + * @return string + */ public function getUnderline() { return $this->_underline; } + /** + * Set underline + * + * @param string $pValue + * @return PHPWord_Style_Font + */ public function setUnderline($pValue = PHPWord_Style_Font::UNDERLINE_NONE) { if ($pValue == '') { @@ -227,49 +395,90 @@ public function setUnderline($pValue = PHPWord_Style_Font::UNDERLINE_NONE) return $this; } + /** + * Get strikethrough + * + * @return bool + */ public function getStrikethrough() { return $this->_strikethrough; } + /** + * Set strikethrough + * + * @param bool $pValue + * @return PHPWord_Style_Font + */ public function setStrikethrough($pValue = false) { - if ($pValue == '') { + if (!is_bool($pValue)) { $pValue = false; } $this->_strikethrough = $pValue; return $this; } + /** + * Get font color + * + * @return string + */ public function getColor() { return $this->_color; } - public function setColor($pValue = '000000') + /** + * Set font color + * + * @param string $pValue + * @return PHPWord_Style_Font + */ + public function setColor($pValue = PHPWord::DEFAULT_FONT_COLOR) { + if (is_null($pValue) || $pValue == '') { + $pValue = PHPWord::DEFAULT_FONT_COLOR; + } $this->_color = $pValue; return $this; } + /** + * Get foreground/highlight color + * + * @return bool + */ public function getFgColor() { return $this->_fgColor; } + /** + * Set foreground/highlight color + * + * @param string $pValue + * @return PHPWord_Style_Font + */ public function setFgColor($pValue = null) { $this->_fgColor = $pValue; return $this; } + /** + * Get style type + * + * @return string + */ public function getStyleType() { return $this->_type; } /** - * Get Paragraph style + * Get paragraph style * * @return PHPWord_Style_Paragraph */ @@ -277,4 +486,59 @@ public function getParagraphStyle() { return $this->_paragraphStyle; } + + /** + * Set the line height + * + * @param int|float|string $lineHeight + * @return $this + * @throws InvalidStyleException + */ + public function setLineHeight($lineHeight) + { + if (is_string($lineHeight)) { + $lineHeight = floatval(preg_replace('/[^0-9\.\,]/', '', $lineHeight)); + } + + if ((!is_integer($lineHeight) && !is_float($lineHeight)) || !$lineHeight) { + throw new InvalidStyleException('Line height must be a valid number'); + } + + $this->lineHeight = $lineHeight; + $this->getParagraphStyle()->setLineHeight($lineHeight); + return $this; + } + + /** + * @return int|float + */ + public function getLineHeight() + { + return $this->lineHeight; + } + + /** + * Get Font Content Type + * + * @return bool + */ + public function getHint() + { + return $this->_hint; + } + + /** + * Set Font Content Type + * + * @param string $pValue + * @return PHPWord_Style_Font + */ + public function setHint($pValue = PHPWord::DEFAULT_FONT_CONTENT_TYPE) + { + if (is_null($pValue) || $pValue == '') { + $pValue = PHPWord::DEFAULT_FONT_CONTENT_TYPE; + } + $this->_hint = $pValue; + return $this; + } } diff --git a/Classes/PHPWord/Style/Image.php b/Classes/PHPWord/Style/Image.php index 47a71cba3f..4453463a38 100755 --- a/Classes/PHPWord/Style/Image.php +++ b/Classes/PHPWord/Style/Image.php @@ -173,4 +173,4 @@ public function getWrappingStyle() { return $this->wrappingStyle; } -} \ No newline at end of file +} diff --git a/Classes/PHPWord/Style/Paragraph.php b/Classes/PHPWord/Style/Paragraph.php index ab285ebea3..754589cb39 100755 --- a/Classes/PHPWord/Style/Paragraph.php +++ b/Classes/PHPWord/Style/Paragraph.php @@ -25,11 +25,21 @@ * @version 0.7.0 */ +use PhpOffice\PhpWord\Exceptions\InvalidStyleException; + /** * PHPWord_Style_Paragraph */ class PHPWord_Style_Paragraph { + const LINE_HEIGHT = 240; + + /** + * Text line height + * + * @var int + */ + private $lineHeight; /** * Paragraph alignment @@ -73,18 +83,71 @@ class PHPWord_Style_Paragraph */ private $_indent; + /** + * Hanging by how much + * + * @var int + */ + private $_hanging; /** - * New Paragraph Style + * Parent style + * + * @var string + */ + private $_basedOn = 'Normal'; + + /** + * Style for next paragraph + * + * @var string + */ + private $_next; + + /** + * Allow first/last line to display on a separate page + * + * @var bool */ - public function __construct() + private $_widowControl = true; + + /** + * Keep paragraph with next paragraph + * + * @var bool + */ + private $_keepNext = false; + + /** + * Keep all lines on one page + * + * @var bool + */ + private $_keepLines = false; + + /** + * Start paragraph on next page + * + * @var bool + */ + private $_pageBreakBefore = false; + + /** + * @param array $style + * @return $this + */ + public function setArrayStyle(array $style = array()) { - $this->_align = null; - $this->_spaceBefore = null; - $this->_spaceAfter = null; - $this->_spacing = null; - $this->_tabs = null; - $this->_indent = null; + foreach ($style as $key => $value) { + if ($key === 'line-height') { + null; + } elseif (substr($key, 0, 1) !== '_') { + $key = '_' . $key; + } + $this->setStyleValue($key, $value); + } + + return $this; } /** @@ -95,16 +158,19 @@ public function __construct() */ public function setStyleValue($key, $value) { - if ($key == '_indent') { - $value = (int)$value * 720; // 720 twips per indent - } - if ($key == '_spacing') { + if ($key == '_indent' || $key == '_hanging') { + $value = $value * 720; + } elseif ($key == '_spacing') { $value += 240; // because line height of 1 matches 240 twips - } - if ($key === '_tabs') { - $value = new PHPWord_Style_Tabs($value); + } elseif ($key === 'line-height') { + $this->setLineHeight($value); + return; } $this->$key = $value; + $method = 'set' . substr($key, 1); + if (method_exists($this, $method)) { + $this->$method($value); + } } /** @@ -221,6 +287,28 @@ public function setIndent($pValue = null) return $this; } + /** + * Get hanging + * + * @return int + */ + public function getHanging() + { + return $this->_hanging; + } + + /** + * Set hanging + * + * @param int $pValue + * @return PHPWord_Style_Paragraph + */ + public function setHanging($pValue = null) + { + $this->_hanging = $pValue; + return $this; + } + /** * Get tabs * @@ -230,4 +318,192 @@ public function getTabs() { return $this->_tabs; } -} \ No newline at end of file + + /* + * Set tabs + * + * @param array $pValue + * @return PHPWord_Style_Paragraph + */ + public function setTabs($pValue = null) + { + if (is_array($pValue)) { + $this->_tabs = new PHPWord_Style_Tabs($pValue); + } + return $this; + } + + /** + * Get parent style ID + * + * @return string + */ + public function getBasedOn() + { + return $this->_basedOn; + } + + /** + * Set parent style ID + * + * @param string $pValue + * @return PHPWord_Style_Paragraph + */ + public function setBasedOn($pValue = 'Normal') + { + $this->_basedOn = $pValue; + return $this; + } + + /** + * Get style for next paragraph + * + * @return string + */ + public function getNext() + { + return $this->_next; + } + + /** + * Set style for next paragraph + * + * @param string $pValue + * @return PHPWord_Style_Paragraph + */ + public function setNext($pValue = null) + { + $this->_next = $pValue; + return $this; + } + + /** + * Get allow first/last line to display on a separate page setting + * + * @return bool + */ + public function getWidowControl() + { + return $this->_widowControl; + } + + /** + * Set keep paragraph with next paragraph setting + * + * @param bool $pValue + * @return PHPWord_Style_Paragraph + */ + public function setWidowControl($pValue = true) + { + if (!is_bool($pValue)) { + $pValue = true; + } + $this->_widowControl = $pValue; + return $this; + } + + /** + * Get keep paragraph with next paragraph setting + * + * @return bool + */ + public function getKeepNext() + { + return $this->_keepNext; + } + + /** + * Set keep paragraph with next paragraph setting + * + * @param bool $pValue + * @return PHPWord_Style_Paragraph + */ + public function setKeepNext($pValue = false) + { + if (!is_bool($pValue)) { + $pValue = false; + } + $this->_keepNext = $pValue; + return $this; + } + + /** + * Get keep all lines on one page setting + * + * @return bool + */ + public function getKeepLines() + { + return $this->_keepLines; + } + + /** + * Set keep all lines on one page setting + * + * @param bool $pValue + * @return PHPWord_Style_Paragraph + */ + public function setKeepLines($pValue = false) + { + if (!is_bool($pValue)) { + $pValue = false; + } + $this->_keepLines = $pValue; + return $this; + } + + /** + * Get start paragraph on next page setting + * + * @return bool + */ + public function getPageBreakBefore() + { + return $this->_pageBreakBefore; + } + + /** + * Set start paragraph on next page setting + * + * @param bool $pValue + * @return PHPWord_Style_Paragraph + */ + public function setPageBreakBefore($pValue = false) + { + if (!is_bool($pValue)) { + $pValue = false; + } + $this->_pageBreakBefore = $pValue; + return $this; + } + + /** + * Set the line height + * + * @param int|float|string $lineHeight + * @return $this + * @throws InvalidStyleException + */ + public function setLineHeight($lineHeight) + { + if (is_string($lineHeight)) { + $lineHeight = floatval(preg_replace('/[^0-9\.\,]/', '', $lineHeight)); + } + + if ((!is_integer($lineHeight) && !is_float($lineHeight)) || !$lineHeight) { + throw new InvalidStyleException('Line height must be a valid number'); + } + + $this->lineHeight = $lineHeight; + $this->setSpacing($lineHeight * self::LINE_HEIGHT); + return $this; + } + + /** + * @return int|float + */ + public function getLineHeight() + { + return $this->lineHeight; + } +} diff --git a/Classes/PHPWord/Style/Row.php b/Classes/PHPWord/Style/Row.php new file mode 100644 index 0000000000..c7140d5897 --- /dev/null +++ b/Classes/PHPWord/Style/Row.php @@ -0,0 +1,90 @@ +$key = $value; + } + + public function setTblHeader($pValue = false) + { + if (!is_bool($pValue)) { + $pValue = false; + } + $this->_tblHeader = $pValue; + return $this; + } + + public function getTblHeader() + { + return $this->_tblHeader; + } + + public function setCantSplit($pValue = false) + { + if (!is_bool($pValue)) { + $pValue = false; + } + $this->_cantSplit = $pValue; + return $this; + } + + public function getCantSplit() + { + return $this->_cantSplit; + } +} diff --git a/Classes/PHPWord/Style/TOC.php b/Classes/PHPWord/Style/TOC.php index 501604b458..e7adfc41df 100755 --- a/Classes/PHPWord/Style/TOC.php +++ b/Classes/PHPWord/Style/TOC.php @@ -85,7 +85,7 @@ public function getTabPos() */ public function setTabPos($pValue) { - $this->_tabLeader = $pValue; + $this->_tabPos = $pValue; } /** diff --git a/Classes/PHPWord/Style/Tab.php b/Classes/PHPWord/Style/Tab.php index a280eebb27..f8ee4b9b8e 100755 --- a/Classes/PHPWord/Style/Tab.php +++ b/Classes/PHPWord/Style/Tab.php @@ -92,7 +92,7 @@ class PHPWord_Style_Tab * @param int $position Must be an integer; otherwise defaults to 0. * @param string $leader Defaults to NULL if value is not possible. */ - public function __construct($val = NULL, $position = 0, $leader = NULL) + public function __construct($val = null, $position = 0, $leader = null) { // Default to clear if the stop type is not matched $this->_val = (self::isStopType($val)) ? $val : 'clear'; @@ -101,7 +101,7 @@ public function __construct($val = NULL, $position = 0, $leader = NULL) $this->_position = (is_numeric($position)) ? intval($position) : 0; // Default to NULL if no tab leader - $this->_leader = (self::isLeaderType($leader)) ? $leader : NULL; + $this->_leader = (self::isLeaderType($leader)) ? $leader : null; } /** @@ -109,7 +109,7 @@ public function __construct($val = NULL, $position = 0, $leader = NULL) * * @param PHPWord_Shared_XMLWriter $objWriter */ - public function toXml(PHPWord_Shared_XMLWriter &$objWriter = NULL) + public function toXml(PHPWord_Shared_XMLWriter &$objWriter = null) { if (isset($objWriter)) { $objWriter->startElement("w:tab"); @@ -143,4 +143,4 @@ private static function isLeaderType($attribute) { return in_array($attribute, self::$_possibleLeaders); } -} \ No newline at end of file +} diff --git a/Classes/PHPWord/Style/TableFull.php b/Classes/PHPWord/Style/TableFull.php index 4e2a768604..11f094e076 100755 --- a/Classes/PHPWord/Style/TableFull.php +++ b/Classes/PHPWord/Style/TableFull.php @@ -247,7 +247,7 @@ public function setBgColor($pValue = null) /** * Set TLRBVH Border Size * - * @param int $pValue + * @param int $pValue Border size in eighths of a point (1/8 point) */ public function setBorderSize($pValue = null) { @@ -466,6 +466,11 @@ public function getCellMarginBottom() return $this->_cellMarginBottom; } + /** + * Set TLRB cell margin + * + * @param int $pValue Margin in twips + */ public function setCellMargin($pValue = null) { $this->_cellMarginTop = $pValue; diff --git a/Classes/PHPWord/Style/Tabs.php b/Classes/PHPWord/Style/Tabs.php index ebad8fbbec..144d2a5d01 100755 --- a/Classes/PHPWord/Style/Tabs.php +++ b/Classes/PHPWord/Style/Tabs.php @@ -51,7 +51,7 @@ public function __construct(array $tabs) * * @param PHPWord_Shared_XMLWriter $objWriter */ - public function toXml(PHPWord_Shared_XMLWriter &$objWriter = NULL) + public function toXml(PHPWord_Shared_XMLWriter &$objWriter = null) { if (isset($objWriter)) { $objWriter->startElement("w:tabs"); @@ -61,4 +61,4 @@ public function toXml(PHPWord_Shared_XMLWriter &$objWriter = NULL) $objWriter->endElement(); } } -} \ No newline at end of file +} diff --git a/Classes/PHPWord/TOC.php b/Classes/PHPWord/TOC.php index 1366f0c3e3..ae514a54d1 100755 --- a/Classes/PHPWord/TOC.php +++ b/Classes/PHPWord/TOC.php @@ -152,4 +152,4 @@ public static function getStyleFont() { return self::$_styleFont; } -} \ No newline at end of file +} diff --git a/Classes/PHPWord/Template.php b/Classes/PHPWord/Template.php index 83a45949c1..840d22950a 100755 --- a/Classes/PHPWord/Template.php +++ b/Classes/PHPWord/Template.php @@ -64,7 +64,7 @@ public function __construct($strFilename) if ($this->_tempFileName !== false) { // Copy the source File to the temp File if (!copy($strFilename, $this->_tempFileName)) { - throw new PHPWord_Exception('Could not copy the template from ' . $strFilename . ' to ' . $this->_tempFileName . '.'); + throw new PHPWord_Exception("Could not copy the template from {$strFilename} to {$this->_tempFileName}."); } $this->_objZip = new ZipArchive(); @@ -76,13 +76,44 @@ public function __construct($strFilename) } } + /** + * Applies XSL style sheet to template's parts + * + * @param DOMDocument &$xslDOMDocument + * @param array $xslOptions = array() + * @param string $xslOptionsURI = '' + */ + public function applyXslStyleSheet(&$xslDOMDocument, $xslOptions = array(), $xslOptionsURI = '') + { + $processor = new \XSLTProcessor(); + + $processor->importStylesheet($xslDOMDocument); + + if ($processor->setParameter($xslOptionsURI, $xslOptions) === false) { + throw new \Exception('Could not set values for the given XSL style sheet parameters.'); + } + + $xmlDOMDocument = new \DOMDocument(); + if ($xmlDOMDocument->loadXML($this->_documentXML) === false) { + throw new \Exception('Could not load XML from the given template.'); + } + + $xmlTransformed = $processor->transformToXml($xmlDOMDocument); + if ($xmlTransformed === false) { + throw new \Exception('Could not transform the given XML document.'); + } + + $this->_documentXML = $xmlTransformed; + } + /** * Set a Template value * * @param mixed $search * @param mixed $replace + * @param integer $limit */ - public function setValue($search, $replace) + public function setValue($search, $replace, $limit = -1) { $pattern = '|\$\{([^\}]+)\}|U'; preg_match_all($pattern, $this->_documentXML, $matches); @@ -100,9 +131,16 @@ public function setValue($search, $replace) if (!PHPWord_Shared_String::IsUTF8($replace)) { $replace = utf8_encode($replace); } + $replace = htmlspecialchars($replace); + } else { + foreach ($replace as $key => $value) { + $replace[$key] = htmlspecialchars($value); + } } - $this->_documentXML = str_replace($search, $replace, $this->_documentXML); + $regExpDelim = '/'; + $escapedSearch = preg_quote($search, $regExpDelim); + $this->_documentXML = preg_replace("{$regExpDelim}{$escapedSearch}{$regExpDelim}u", $replace, $this->_documentXML, $limit); } /** @@ -114,12 +152,110 @@ public function getVariables() return $matches[1]; } + /** + * Find the start position of the nearest table row before $offset + * + * @param mixed $offset + */ + private function _findRowStart($offset) + { + $rowStart = strrpos($this->_documentXML, "_documentXML) - $offset) * -1)); + if (!$rowStart) { + $rowStart = strrpos($this->_documentXML, "", ((strlen($this->_documentXML) - $offset) * -1)); + } + if (!$rowStart) { + throw new Exception("Can not find the start position of the row to clone."); + return false; + } + return $rowStart; + } + + /** + * Find the end position of the nearest table row after $offset + * + * @param mixed $offset + */ + private function _findRowEnd($offset) + { + $rowEnd = strpos($this->_documentXML, "", $offset) + 7; + return $rowEnd; + } + + /** + * Get a slice of a string + * + * @param mixed $offset + */ + private function _getSlice($startPosition, $endPosition = 0) + { + if (!$endPosition) { + $endPosition = strlen($this->_documentXML); + } + return substr($this->_documentXML, $startPosition, ($endPosition - $startPosition)); + } + + /** + * Clone a table row in a template document + * + * @param mixed $search + * @param mixed $numberOfClones + */ + public function cloneRow($search, $numberOfClones) + { + if (substr($search, 0, 2) !== '${' && substr($search, -1) !== '}') { + $search = '${'.$search.'}'; + } + + $tagPos = strpos($this->_documentXML, $search); + if (!$tagPos) { + throw new Exception("Can not clone row, template variable not found or variable contains markup."); + return false; + } + + $rowStart = $this->_findRowStart($tagPos); + $rowEnd = $this->_findRowEnd($tagPos); + $xmlRow = $this->_getSlice($rowStart, $rowEnd); + + // Check if there's a cell spanning multiple rows. + if (preg_match('##', $xmlRow)) { + $extraRowStart = $rowEnd; + $extraRowEnd = $rowEnd; + while (true) { + $extraRowStart = $this->_findRowStart($extraRowEnd + 1); + $extraRowEnd = $this->_findRowEnd($extraRowEnd + 1); + + // If extraRowEnd is lower then 7, there was no next row found. + if ($extraRowEnd < 7) { + break; + } + + // If tmpXmlRow doesn't contain continue, this row is no longer part of the spanned row. + $tmpXmlRow = $this->_getSlice($extraRowStart, $extraRowEnd); + if (!preg_match('##', $tmpXmlRow) && !preg_match('##', $tmpXmlRow)) { + break; + } + // This row was a spanned row, update $rowEnd and search for the next row. + $rowEnd = $extraRowEnd; + } + $xmlRow = $this->_getSlice($rowStart, $rowEnd); + } + + $result = $this->_getSlice(0, $rowStart); + for ($i = 1; $i <= $numberOfClones; $i++) { + $result .= preg_replace('/\$\{(.*?)\}/', '\${\\1#'.$i.'}', $xmlRow); + } + $result .= $this->_getSlice($rowEnd); + + $this->_documentXML = $result; + } + /** * Save Template * * @return string */ - public function save() { + public function save() + { $this->_objZip->addFromString('word/document.xml', $this->_documentXML); // Close zip file @@ -135,7 +271,8 @@ public function save() { * * @param string $strFilename */ - public function saveAs($strFilename) { + public function saveAs($strFilename) + { $tempFilename = $this->save(); if (file_exists($strFilename)) { diff --git a/Classes/PHPWord/Writer/ODText.php b/Classes/PHPWord/Writer/ODText.php index 3414179da7..6ec25cbaac 100755 --- a/Classes/PHPWord/Writer/ODText.php +++ b/Classes/PHPWord/Writer/ODText.php @@ -141,7 +141,8 @@ public function save($pFilename = null) // Add META-INF/manifest.xml $objZip->addFromString('META-INF/manifest.xml', $this->getWriterPart('manifest')->writeManifest($this->_document)); - // Add media + // Add media. Has not used yet. Legacy from PHPExcel. + // @codeCoverageIgnoreStart for ($i = 0; $i < $this->getDrawingHashTable()->count(); ++$i) { if ($this->getDrawingHashTable()->getByIndex($i) instanceof PHPWord_Shape_Drawing) { $imageContents = null; @@ -161,7 +162,7 @@ public function save($pFilename = null) } $objZip->addFromString('Pictures/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()), $imageContents); - } else if ($this->getDrawingHashTable()->getByIndex($i) instanceof PHPWord_Shape_MemoryDrawing) { + } elseif ($this->getDrawingHashTable()->getByIndex($i) instanceof PHPWord_Shape_MemoryDrawing) { ob_start(); call_user_func( $this->getDrawingHashTable()->getByIndex($i)->getRenderingFunction(), @@ -173,6 +174,7 @@ public function save($pFilename = null) $objZip->addFromString('Pictures/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()), $imageContents); } } + // @codeCoverageIgnoreEnd // Close file if ($objZip->close() === false) { @@ -212,7 +214,7 @@ public function getPHPWord() * * @param PHPWord $pPHPWord PHPWord object * @throws Exception - * @return PHPWord_Writer_PowerPoint2007 + * @return PHPWord_Writer_ODText */ public function setPHPWord(PHPWord $pPHPWord = null) { @@ -236,7 +238,7 @@ public function getDrawingHashTable() * @param string $pPartName Writer part name * @return PHPWord_Writer_ODText_WriterPart */ - function getWriterPart($pPartName = '') + public function getWriterPart($pPartName = '') { if ($pPartName != '' && isset($this->_writerParts[strtolower($pPartName)])) { return $this->_writerParts[strtolower($pPartName)]; @@ -261,7 +263,7 @@ public function getUseDiskCaching() * @param boolean $pValue * @param string $pDirectory Disk caching directory * @throws Exception Exception when directory does not exist - * @return PHPWord_Writer_PowerPoint2007 + * @return PHPWord_Writer_ODText */ public function setUseDiskCaching($pValue = false, $pDirectory = null) { @@ -287,4 +289,4 @@ public function getDiskCachingDirectory() { return $this->_diskCachingDirectory; } -} \ No newline at end of file +} diff --git a/Classes/PHPWord/Writer/ODText/Content.php b/Classes/PHPWord/Writer/ODText/Content.php index d2690aff9c..c33635cc2b 100755 --- a/Classes/PHPWord/Writer/ODText/Content.php +++ b/Classes/PHPWord/Writer/ODText/Content.php @@ -115,7 +115,7 @@ public function writeContent(PHPWord $pPHPWord = null) $numPStyles++; $pPHPWord->addParagraphStyle('P' . $numPStyles, array()); - $element->setParagraph('P' . $numPStyles); + $element->setParagraphStyle('P' . $numPStyles); } } } @@ -145,10 +145,10 @@ public function writeContent(PHPWord $pPHPWord = null) } } } - if (!in_array('Arial', $arrFonts)) { + if (!in_array(PHPWord::DEFAULT_FONT_NAME, $arrFonts)) { $objWriter->startElement('style:font-face'); - $objWriter->writeAttribute('style:name', 'Arial'); - $objWriter->writeAttribute('svg:font-family', 'Arial'); + $objWriter->writeAttribute('style:name', PHPWord::DEFAULT_FONT_NAME); + $objWriter->writeAttribute('svg:font-family', PHPWord::DEFAULT_FONT_NAME); $objWriter->endElement(); } } @@ -249,31 +249,29 @@ public function writeContent(PHPWord $pPHPWord = null) foreach ($_elements as $element) { if ($element instanceof PHPWord_Section_Text) { $this->_writeText($objWriter, $element); - } /* elseif($element instanceof PHPWord_Section_TextRun) { - $this->_writeTextRun($objWriter, $element); - } elseif($element instanceof PHPWord_Section_Link) { - $this->_writeLink($objWriter, $element); - } elseif($element instanceof PHPWord_Section_Title) { - $this->_writeTitle($objWriter, $element); - }*/ elseif ($element instanceof PHPWord_Section_TextBreak) { + } elseif ($element instanceof PHPWord_Section_TextRun) { + $this->_writeTextRun($objWriter, $element); + } elseif ($element instanceof PHPWord_Section_TextBreak) { $this->_writeTextBreak($objWriter); - } /* elseif($element instanceof PHPWord_Section_PageBreak) { - $this->_writePageBreak($objWriter); - } elseif($element instanceof PHPWord_Section_Table) { - $this->_writeTable($objWriter, $element); - } elseif($element instanceof PHPWord_Section_ListItem) { - $this->_writeListItem($objWriter, $element); - } elseif($element instanceof PHPWord_Section_Image || - $element instanceof PHPWord_Section_MemoryImage) { - $this->_writeImage($objWriter, $element); - } elseif($element instanceof PHPWord_Section_Object) { - $this->_writeObject($objWriter, $element); - } elseif($element instanceof PHPWord_TOC) { - $this->_writeTOC($objWriter); - }*/ - else { - print_r($element); - echo '
'; + } elseif ($element instanceof PHPWord_Section_Link) { + $this->writeUnsupportedElement($objWriter, 'Link'); + } elseif ($element instanceof PHPWord_Section_Title) { + $this->writeUnsupportedElement($objWriter, 'Title'); + } elseif ($element instanceof PHPWord_Section_PageBreak) { + $this->writeUnsupportedElement($objWriter, 'Page Break'); + } elseif ($element instanceof PHPWord_Section_Table) { + $this->writeUnsupportedElement($objWriter, 'Table'); + } elseif ($element instanceof PHPWord_Section_ListItem) { + $this->writeUnsupportedElement($objWriter, 'List Item'); + } elseif ($element instanceof PHPWord_Section_Image || + $element instanceof PHPWord_Section_MemoryImage) { + $this->writeUnsupportedElement($objWriter, 'Image'); + } elseif ($element instanceof PHPWord_Section_Object) { + $this->writeUnsupportedElement($objWriter, 'Object'); + } elseif ($element instanceof PHPWord_TOC) { + $this->writeUnsupportedElement($objWriter, 'TOC'); + } else { + $this->writeUnsupportedElement($objWriter, 'Element'); } } @@ -292,19 +290,32 @@ public function writeContent(PHPWord $pPHPWord = null) return $objWriter->getData(); } - protected function _writeText(PHPWord_Shared_XMLWriter $objWriter = null, PHPWord_Section_Text $text, $withoutP = false) - { + /** + * Write text + * + * @param PHPWord_Shared_XMLWriter $objWriter + * @param PHPWord_Section_Text $text + * @param bool $withoutP + */ + protected function _writeText( + PHPWord_Shared_XMLWriter $objWriter = null, + PHPWord_Section_Text $text, + $withoutP = false + ) { $styleFont = $text->getFontStyle(); $styleParagraph = $text->getParagraphStyle(); - $SfIsObject = ($styleFont instanceof PHPWord_Style_Font) ? true : false; + // @todo Commented for TextRun. Should really checkout this value + // $SfIsObject = ($styleFont instanceof PHPWord_Style_Font) ? true : false; + $SfIsObject = false; if ($SfIsObject) { // Don't never be the case, because I browse all sections for cleaning all styles not declared die('PHPWord : $SfIsObject wouldn\'t be an object'); } else { - // text:p - $objWriter->startElement('text:p'); + if (!$withoutP) { + $objWriter->startElement('text:p'); // text:p + } if (empty($styleFont)) { if (empty($styleParagraph)) { $objWriter->writeAttribute('text:style-name', 'P1'); @@ -324,10 +335,36 @@ protected function _writeText(PHPWord_Shared_XMLWriter $objWriter = null, PHPWor $objWriter->writeRaw($text->getText()); $objWriter->endElement(); } - $objWriter->endElement(); + if (!$withoutP) { + $objWriter->endElement(); // text:p + } + } + } + + /** + * Write TextRun section + * + * @param PHPWord_Shared_XMLWriter $objWriter + * @param PHPWord_Section_TextRun $textrun + * @todo Enable all other section types + */ + protected function _writeTextRun(PHPWord_Shared_XMLWriter $objWriter = null, PHPWord_Section_TextRun $textrun) + { + $elements = $textrun->getElements(); + $objWriter->startElement('text:p'); + if (count($elements) > 0) { + foreach ($elements as $element) { + if ($element instanceof PHPWord_Section_Text) { + $this->_writeText($objWriter, $element, true); + } + } } + $objWriter->endElement(); } + /** + * Write TextBreak + */ protected function _writeTextBreak(PHPWord_Shared_XMLWriter $objWriter = null) { $objWriter->startElement('text:p'); @@ -335,7 +372,26 @@ protected function _writeTextBreak(PHPWord_Shared_XMLWriter $objWriter = null) $objWriter->endElement(); } - private function _writeEndSection(PHPWord_Shared_XMLWriter $objWriter = null, PHPWord_Section $section) + // @codeCoverageIgnoreStart + private function _writeEndSection(PHPWord_Shared_XMLWriter $objWriter = null, PHPWord_Section $section = null) { } + + private function _writeSection(PHPWord_Shared_XMLWriter $objWriter = null, PHPWord_Section $section = null) + { + } + // @codeCoverageIgnoreEnd + + /** + * Write unsupported element + * + * @param PHPWord_Shared_XMLWriter $objWriter + * @param string $element + */ + private function writeUnsupportedElement($objWriter, $element) + { + $objWriter->startElement('text:p'); + $objWriter->writeRaw("{$element}"); + $objWriter->endElement(); + } } diff --git a/Classes/PHPWord/Writer/ODText/Manifest.php b/Classes/PHPWord/Writer/ODText/Manifest.php index f981594153..c3c2898121 100755 --- a/Classes/PHPWord/Writer/ODText/Manifest.php +++ b/Classes/PHPWord/Writer/ODText/Manifest.php @@ -77,6 +77,8 @@ public function writeManifest(PHPWord $pPHPWord = null) $objWriter->writeAttribute('manifest:full-path', 'styles.xml'); $objWriter->endElement(); + // Not used yet. Legacy from PHPExcel + // @codeCoverageIgnoreStart for ($i = 0; $i < $this->getParentWriter()->getDrawingHashTable()->count(); ++$i) { if ($this->getParentWriter()->getDrawingHashTable()->getByIndex($i) instanceof PHPWord_Shape_Drawing) { $extension = strtolower($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getExtension()); @@ -86,7 +88,7 @@ public function writeManifest(PHPWord $pPHPWord = null) $objWriter->writeAttribute('manifest:media-type', $mimeType); $objWriter->writeAttribute('manifest:full-path', 'Pictures/' . str_replace(' ', '_', $this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getIndexedFilename())); $objWriter->endElement(); - } else if ($this->getParentWriter()->getDrawingHashTable()->getByIndex($i) instanceof PHPWord_Shape_MemoryDrawing) { + } elseif ($this->getParentWriter()->getDrawingHashTable()->getByIndex($i) instanceof PHPWord_Shape_MemoryDrawing) { $extension = strtolower($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getMimeType()); $extension = explode('/', $extension); $extension = $extension[1]; @@ -99,6 +101,7 @@ public function writeManifest(PHPWord $pPHPWord = null) $objWriter->endElement(); } } + // @codeCoverageIgnoreEnd $objWriter->endElement(); diff --git a/Classes/PHPWord/Writer/ODText/Mimetype.php b/Classes/PHPWord/Writer/ODText/Mimetype.php index 439ada1abb..def40db4e0 100755 --- a/Classes/PHPWord/Writer/ODText/Mimetype.php +++ b/Classes/PHPWord/Writer/ODText/Mimetype.php @@ -42,5 +42,4 @@ public function writeMimetype(PHPWord $pPHPWord = null) return 'application/vnd.oasis.opendocument.text'; } - } diff --git a/Classes/PHPWord/Writer/ODText/Styles.php b/Classes/PHPWord/Writer/ODText/Styles.php index 3c485e551b..7f38880942 100755 --- a/Classes/PHPWord/Writer/ODText/Styles.php +++ b/Classes/PHPWord/Writer/ODText/Styles.php @@ -104,10 +104,10 @@ public function writeStyles(PHPWord $pPHPWord = null) } } } - if (!in_array('Arial', $arrFonts)) { + if (!in_array(PHPWord::DEFAULT_FONT_NAME, $arrFonts)) { $objWriter->startElement('style:font-face'); - $objWriter->writeAttribute('style:name', 'Arial'); - $objWriter->writeAttribute('svg:font-family', 'Arial'); + $objWriter->writeAttribute('style:name', PHPWord::DEFAULT_FONT_NAME); + $objWriter->writeAttribute('svg:font-family', PHPWord::DEFAULT_FONT_NAME); $objWriter->endElement(); } $objWriter->endElement(); @@ -132,17 +132,17 @@ public function writeStyles(PHPWord $pPHPWord = null) // style:text-properties $objWriter->startElement('style:text-properties'); $objWriter->writeAttribute('style:use-window-font-color', 'true'); - $objWriter->writeAttribute('style:font-name', 'Arial'); - $objWriter->writeAttribute('fo:font-size', '10pt'); + $objWriter->writeAttribute('style:font-name', PHPWord::DEFAULT_FONT_NAME); + $objWriter->writeAttribute('fo:font-size', PHPWord::DEFAULT_FONT_SIZE . 'pt'); $objWriter->writeAttribute('fo:language', 'fr'); $objWriter->writeAttribute('fo:country', 'FR'); $objWriter->writeAttribute('style:letter-kerning', 'true'); - $objWriter->writeAttribute('style:font-name-asian', 'Arial2'); - $objWriter->writeAttribute('style:font-size-asian', '10pt'); + $objWriter->writeAttribute('style:font-name-asian', PHPWord::DEFAULT_FONT_NAME . '2'); + $objWriter->writeAttribute('style:font-size-asian', PHPWord::DEFAULT_FONT_SIZE . 'pt'); $objWriter->writeAttribute('style:language-asian', 'zh'); $objWriter->writeAttribute('style:country-asian', 'CN'); - $objWriter->writeAttribute('style:font-name-complex', 'Arial2'); - $objWriter->writeAttribute('style:font-size-complex', '10pt'); + $objWriter->writeAttribute('style:font-name-complex', PHPWord::DEFAULT_FONT_NAME . '2'); + $objWriter->writeAttribute('style:font-size-complex', PHPWord::DEFAULT_FONT_SIZE . 'pt'); $objWriter->writeAttribute('style:language-complex', 'hi'); $objWriter->writeAttribute('style:country-complex', 'IN'); $objWriter->writeAttribute('fo:hyphenate', 'false'); @@ -168,9 +168,9 @@ public function writeStyles(PHPWord $pPHPWord = null) // style:text-properties $objWriter->startElement('style:text-properties'); - $objWriter->writeAttribute('fo:font-size', ($style->getSize() / 2) . 'pt'); - $objWriter->writeAttribute('style:font-size-asian', ($style->getSize() / 2) . 'pt'); - $objWriter->writeAttribute('style:font-size-complex', ($style->getSize() / 2) . 'pt'); + $objWriter->writeAttribute('fo:font-size', ($style->getSize()) . 'pt'); + $objWriter->writeAttribute('style:font-size-asian', ($style->getSize()) . 'pt'); + $objWriter->writeAttribute('style:font-size-complex', ($style->getSize()) . 'pt'); if ($style->getItalic()) { $objWriter->writeAttribute('fo:font-style', 'italic'); $objWriter->writeAttribute('style:font-style-asian', 'italic'); @@ -182,8 +182,8 @@ public function writeStyles(PHPWord $pPHPWord = null) } $objWriter->endElement(); $objWriter->endElement(); - } // PHPWord_Style_Paragraph - elseif ($style instanceof PHPWord_Style_Paragraph) { + } elseif ($style instanceof PHPWord_Style_Paragraph) { + // PHPWord_Style_Paragraph // style:style $objWriter->startElement('style:style'); $objWriter->writeAttribute('style:name', $styleName); @@ -197,9 +197,8 @@ public function writeStyles(PHPWord $pPHPWord = null) $objWriter->endElement(); $objWriter->endElement(); - - } // PHPWord_Style_TableFull - elseif ($style instanceof PHPWord_Style_TableFull) { + } elseif ($style instanceof PHPWord_Style_TableFull) { + // PHPWord_Style_TableFull } } } diff --git a/Classes/PHPWord/Writer/RTF.php b/Classes/PHPWord/Writer/RTF.php index ebaa00dad8..80889ebe78 100755 --- a/Classes/PHPWord/Writer/RTF.php +++ b/Classes/PHPWord/Writer/RTF.php @@ -81,7 +81,7 @@ public function save($pFilename = null) } $hFile = fopen($pFilename, 'w') or die("can't open file"); - fwrite($hFile, $this->_getData()); + fwrite($hFile, $this->getData()); fclose($hFile); // If a temporary file was used, copy it to the correct file stream @@ -117,7 +117,7 @@ public function getPHPWord() * * @param PHPWord $pPHPWord PHPWord object * @throws Exception - * @return PHPWord_Writer_PowerPoint2007 + * @return PHPWord_Writer_RTF */ public function setPHPWord(PHPWord $pPHPWord = null) { @@ -135,11 +135,11 @@ public function getDrawingHashTable() return $this->_drawingHashTable; } - private function _getData() + private function getData() { // PHPWord object : $this->_document - $this->_fontTable = $this->_getDataFont(); - $this->_colorTable = $this->_getDataColor(); + $this->_fontTable = $this->getDataFont(); + $this->_colorTable = $this->getDataColor(); $sRTFContent = '{\rtf1'; // Set the default character set @@ -148,6 +148,7 @@ private function _getData() $sRTFContent .= '\deff0'; // Set the default tab size (720 twips) $sRTFContent .= '\deftab720'; + $sRTFContent .= PHP_EOL; // Set the font tbl group $sRTFContent .= '{\fonttbl'; foreach ($this->_fontTable as $idx => $font) { @@ -162,7 +163,7 @@ private function _getData() } $sRTFContent .= ';}' . PHP_EOL; // Set the generator - $sRTFContent .= '{\*\generator PHPWord;}'; + $sRTFContent .= '{\*\generator PHPWord;}' . PHP_EOL; // Set the view mode of the document $sRTFContent .= '\viewkind4'; // Set the numberof bytes that follows a unicode character @@ -176,9 +177,10 @@ private function _getData() // Point size (in half-points) above which to kern character pairs $sRTFContent .= '\kerning1'; // Set the font size in half-points - $sRTFContent .= '\fs20'; + $sRTFContent .= '\fs' . (PHPWord::DEFAULT_FONT_SIZE * 2); + $sRTFContent .= PHP_EOL; // Body - $sRTFContent .= $this->_getDataContent(); + $sRTFContent .= $this->getDataContent(); $sRTFContent .= '}'; @@ -186,13 +188,13 @@ private function _getData() return $sRTFContent; } - private function _getDataFont() + private function getDataFont() { $pPHPWord = $this->_document; $arrFonts = array(); - // Default font : Arial - $arrFonts[] = 'Arial'; + // Default font : PHPWord::DEFAULT_FONT_NAME + $arrFonts[] = PHPWord::DEFAULT_FONT_NAME; // PHPWord object : $this->_document // Browse styles @@ -202,7 +204,7 @@ private function _getDataFont() foreach ($styles as $styleName => $style) { // PHPWord_Style_Font if ($style instanceof PHPWord_Style_Font) { - if (in_array($style->getName(), $arrFonts) == FALSE) { + if (in_array($style->getName(), $arrFonts) == false) { $arrFonts[] = $style->getName(); } } @@ -224,7 +226,7 @@ private function _getDataFont() $fStyle = $element->getFontStyle(); if ($fStyle instanceof PHPWord_Style_Font) { - if (in_array($fStyle->getName(), $arrFonts) == FALSE) { + if (in_array($fStyle->getName(), $arrFonts) == false) { $arrFonts[] = $fStyle->getName(); } } @@ -236,7 +238,7 @@ private function _getDataFont() return $arrFonts; } - private function _getDataColor() + private function getDataColor() { $pPHPWord = $this->_document; @@ -252,10 +254,10 @@ private function _getDataColor() if ($style instanceof PHPWord_Style_Font) { $color = $style->getColor(); $fgcolor = $style->getFgColor(); - if (in_array($color, $arrColors) == FALSE && $color != '000000' && !empty($color)) { + if (in_array($color, $arrColors) == false && $color != PHPWord::DEFAULT_FONT_COLOR && !empty($color)) { $arrColors[] = $color; } - if (in_array($fgcolor, $arrColors) == FALSE && $fgcolor != '000000' && !empty($fgcolor)) { + if (in_array($fgcolor, $arrColors) == false && $fgcolor != PHPWord::DEFAULT_FONT_COLOR && !empty($fgcolor)) { $arrColors[] = $fgcolor; } } @@ -277,10 +279,10 @@ private function _getDataColor() $fStyle = $element->getFontStyle(); if ($fStyle instanceof PHPWord_Style_Font) { - if (in_array($fStyle->getColor(), $arrColors) == FALSE) { + if (in_array($fStyle->getColor(), $arrColors) == false) { $arrColors[] = $fStyle->getColor(); } - if (in_array($fStyle->getFgColor(), $arrColors) == FALSE) { + if (in_array($fStyle->getFgColor(), $arrColors) == false) { $arrColors[] = $fStyle->getFgColor(); } } @@ -292,7 +294,7 @@ private function _getDataColor() return $arrColors; } - private function _getDataContent() + private function getDataContent() { $pPHPWord = $this->_document; $sRTFBody = ''; @@ -307,33 +309,30 @@ private function _getDataContent() $_elements = $section->getElements(); foreach ($_elements as $element) { if ($element instanceof PHPWord_Section_Text) { - $sRTFBody .= $this->_getDataContent_writeText($element); - } /* elseif($element instanceof PHPWord_Section_TextRun) { - $this->_writeTextRun($objWriter, $element); - } elseif($element instanceof PHPWord_Section_Link) { - $this->_writeLink($objWriter, $element); - } elseif($element instanceof PHPWord_Section_Title) { - $this->_writeTitle($objWriter, $element); - }*/ - elseif ($element instanceof PHPWord_Section_TextBreak) { - $sRTFBody .= $this->_getDataContent_writeTextBreak(); - } /* elseif($element instanceof PHPWord_Section_PageBreak) { - $this->_writePageBreak($objWriter); - } elseif($element instanceof PHPWord_Section_Table) { - $this->_writeTable($objWriter, $element); - } elseif($element instanceof PHPWord_Section_ListItem) { - $this->_writeListItem($objWriter, $element); - } elseif($element instanceof PHPWord_Section_Image || - $element instanceof PHPWord_Section_MemoryImage) { - $this->_writeImage($objWriter, $element); - } elseif($element instanceof PHPWord_Section_Object) { - $this->_writeObject($objWriter, $element); - } elseif($element instanceof PHPWord_TOC) { - $this->_writeTOC($objWriter); - }*/ - else { - print_r($element); - echo '
'; + $sRTFBody .= $this->getDataContentText($element); + } elseif ($element instanceof PHPWord_Section_TextBreak) { + $sRTFBody .= $this->getDataContentTextBreak(); + } elseif ($element instanceof PHPWord_Section_TextRun) { + $sRTFBody .= $this->getDataContentTextRun($element); + } elseif ($element instanceof PHPWord_Section_Link) { + $sRTFBody .= $this->getDataContentUnsupportedElement('Link'); + } elseif ($element instanceof PHPWord_Section_Title) { + $sRTFBody .= $this->getDataContentUnsupportedElement('Title'); + } elseif ($element instanceof PHPWord_Section_PageBreak) { + $sRTFBody .= $this->getDataContentUnsupportedElement('Page Break'); + } elseif ($element instanceof PHPWord_Section_Table) { + $sRTFBody .= $this->getDataContentUnsupportedElement('Table'); + } elseif ($element instanceof PHPWord_Section_ListItem) { + $sRTFBody .= $this->getDataContentUnsupportedElement('List Item'); + } elseif ($element instanceof PHPWord_Section_Image || + $element instanceof PHPWord_Section_MemoryImage) { + $sRTFBody .= $this->getDataContentUnsupportedElement('Image'); + } elseif ($element instanceof PHPWord_Section_Object) { + $sRTFBody .= $this->getDataContentUnsupportedElement('Object'); + } elseif ($element instanceof PHPWord_TOC) { + $sRTFBody .= $this->getDataContentUnsupportedElement('TOC'); + } else { + $sRTFBody .= $this->getDataContentUnsupportedElement('Other'); } } } @@ -341,7 +340,10 @@ private function _getDataContent() return $sRTFBody; } - private function _getDataContent_writeText(PHPWord_Section_Text $text) + /** + * Get text + */ + private function getDataContentText(PHPWord_Section_Text $text, $withoutP = false) { $sRTFText = ''; @@ -357,7 +359,7 @@ private function _getDataContent_writeText(PHPWord_Section_Text $text) $styleParagraph = PHPWord_Style::getStyle($styleParagraph); } - if ($styleParagraph) { + if ($styleParagraph && !$withoutP) { if ($this->_lastParagraphStyle != $text->getParagraphStyle()) { $sRTFText .= '\pard\nowidctlpar'; if ($styleParagraph->getSpaceAfter() != null) { @@ -376,10 +378,10 @@ private function _getDataContent_writeText(PHPWord_Section_Text $text) $this->_lastParagraphStyle = ''; } - if ($styleFont) { + if ($styleFont instanceof PHPWord_Style_Font) { if ($styleFont->getColor() != null) { $idxColor = array_search($styleFont->getColor(), $this->_colorTable); - if ($idxColor !== FALSE) { + if ($idxColor !== false) { $sRTFText .= '\cf' . ($idxColor + 1); } } else { @@ -387,7 +389,7 @@ private function _getDataContent_writeText(PHPWord_Section_Text $text) } if ($styleFont->getName() != null) { $idxFont = array_search($styleFont->getName(), $this->_fontTable); - if ($idxFont !== FALSE) { + if ($idxFont !== false) { $sRTFText .= '\f' . $idxFont; } } else { @@ -400,7 +402,7 @@ private function _getDataContent_writeText(PHPWord_Section_Text $text) $sRTFText .= '\i'; } if ($styleFont->getSize()) { - $sRTFText .= '\fs' . $styleFont->getSize(); + $sRTFText .= '\fs' . ($styleFont->getSize() * 2); } } if ($this->_lastParagraphStyle != '' || $styleFont) { @@ -408,7 +410,7 @@ private function _getDataContent_writeText(PHPWord_Section_Text $text) } $sRTFText .= $text->getText(); - if ($styleFont) { + if ($styleFont instanceof PHPWord_Style_Font) { $sRTFText .= '\cf0'; $sRTFText .= '\f0'; @@ -419,20 +421,56 @@ private function _getDataContent_writeText(PHPWord_Section_Text $text) $sRTFText .= '\i0'; } if ($styleFont->getSize()) { - $sRTFText .= '\fs20'; + $sRTFText .= '\fs' . (PHPWord::DEFAULT_FONT_SIZE * 2); } } - $sRTFText .= '\par' . PHP_EOL; + if (!$withoutP) { + $sRTFText .= '\par' . PHP_EOL; + } + return $sRTFText; + } + + /** + * Get text run content + */ + private function getDataContentTextRun(PHPWord_Section_TextRun $textrun) + { + $sRTFText = ''; + $elements = $textrun->getElements(); + if (count($elements) > 0) { + $sRTFText .= '\pard\nowidctlpar' . PHP_EOL; + foreach ($elements as $element) { + if ($element instanceof PHPWord_Section_Text) { + $sRTFText .= '{'; + $sRTFText .= $this->getDataContentText($element, true); + $sRTFText .= '}' . PHP_EOL; + } + } + $sRTFText .= '\par' . PHP_EOL; + } return $sRTFText; } - private function _getDataContent_writeTextBreak() + private function getDataContentTextBreak() { $this->_lastParagraphStyle = ''; return '\par' . PHP_EOL; } + /** + * Write unsupported element + * + * @param string $element + */ + private function getDataContentUnsupportedElement($element) + { + $sRTFText = ''; + $sRTFText .= '\pard\nowidctlpar' . PHP_EOL; + $sRTFText .= "{$element}"; + $sRTFText .= '\par' . PHP_EOL; -} \ No newline at end of file + return $sRTFText; + } +} diff --git a/Classes/PHPWord/Writer/Word2007.php b/Classes/PHPWord/Writer/Word2007.php index 6dfc95d343..bd574eb202 100755 --- a/Classes/PHPWord/Writer/Word2007.php +++ b/Classes/PHPWord/Writer/Word2007.php @@ -25,6 +25,9 @@ * @version 0.7.0 */ +use PhpOffice\PhpWord\Exceptions\InvalidImageException; +use PhpOffice\PhpWord\Exceptions\UnsupportedImageTypeException; + /** * Class PHPWord_Writer_Word2007 */ @@ -52,6 +55,8 @@ public function __construct(PHPWord $PHPWord = null) $this->_writerParts['styles'] = new PHPWord_Writer_Word2007_Styles(); $this->_writerParts['header'] = new PHPWord_Writer_Word2007_Header(); $this->_writerParts['footer'] = new PHPWord_Writer_Word2007_Footer(); + $this->_writerParts['footnotes'] = new PHPWord_Writer_Word2007_Footnotes(); + $this->_writerParts['footnotesrels'] = new PHPWord_Writer_Word2007_FootnotesRels(); foreach ($this->_writerParts as $writer) { $writer->setParentWriter($this); @@ -111,12 +116,19 @@ public function save($pFilename = null) } } + $footnoteLinks = array(); + $_footnoteElements = PHPWord_Footnote::getFootnoteLinkElements(); + // loop through footnote link elements + foreach ($_footnoteElements as $element) { + $footnoteLinks[] = $element; + } $_cHdrs = 0; $_cFtrs = 0; $rID = PHPWord_Media::countSectionMediaElements() + 6; $_sections = $this->_document->getSections(); + $footers = array(); foreach ($_sections as $section) { $_headers = $section->getHeaders(); foreach ($_headers as $index => &$_header) { @@ -128,8 +140,8 @@ public function save($pFilename = null) } $_footer = $section->getFooter(); + $footers[++$_cFtrs] = $_footer; if (!is_null($_footer)) { - $_cFtrs++; $_footer->setRelationId(++$rID); $_footerCount = $_footer->getFooterCount(); $_footerFile = 'footer' . $_footerCount . '.xml'; @@ -138,9 +150,27 @@ public function save($pFilename = null) } } + if (PHPWord_Footnote::countFootnoteElements() > 0) { + $_allFootnotesCollection = PHPWord_Footnote::getFootnoteElements(); + $_footnoteFile = 'footnotes.xml'; + $sectionElements[] = array('target'=>$_footnoteFile, 'type'=>'footnotes', 'rID'=>++$rID); + $objZip->addFromString('word/'.$_footnoteFile, $this->getWriterPart('footnotes')->writeFootnotes($_allFootnotesCollection)); + if (count($footnoteLinks) > 0) { + $objZip->addFromString('word/_rels/footnotes.xml.rels', $this->getWriterPart('footnotesrels')->writeFootnotesRels($footnoteLinks)); + } + } + // build docx file // Write dynamic files - $objZip->addFromString('[Content_Types].xml', $this->getWriterPart('contenttypes')->writeContentTypes($this->_imageTypes, $this->_objectTypes, $_cHdrs, $_cFtrs)); + $objZip->addFromString( + '[Content_Types].xml', + $this->getWriterPart('contenttypes')->writeContentTypes( + $this->_imageTypes, + $this->_objectTypes, + $_cHdrs, + $footers + ) + ); $objZip->addFromString('_rels/.rels', $this->getWriterPart('rels')->writeRelationships($this->_document)); $objZip->addFromString('docProps/app.xml', $this->getWriterPart('docprops')->writeDocPropsApp($this->_document)); $objZip->addFromString('docProps/core.xml', $this->getWriterPart('docprops')->writeDocPropsCore($this->_document)); @@ -173,24 +203,38 @@ public function save($pFilename = null) } } - private function _chkContentTypes($src) + /** + * @param string $src + */ + private function checkContentTypes($src) { - $srcInfo = pathinfo($src); - $extension = strtolower($srcInfo['extension']); - if (substr($extension, 0, 3) == 'php') { + $extension = null; + if (stripos(strrev($src), strrev('.php')) === 0) { $extension = 'php'; + } else { + $imageType = exif_imagetype($src); + if ($imageType === IMAGETYPE_JPEG) { + $extension = 'jpg'; + } elseif ($imageType === IMAGETYPE_GIF) { + $extension = 'gif'; + } elseif ($imageType === IMAGETYPE_PNG) { + $extension = 'png'; + } elseif ($imageType === IMAGETYPE_BMP) { + $extension = 'bmp'; + } elseif ($imageType === IMAGETYPE_TIFF_II || $imageType === IMAGETYPE_TIFF_MM) { + $extension = 'tif'; + } } - $_supportedImageTypes = array('jpg', 'jpeg', 'gif', 'png', 'bmp', 'tif', 'tiff', 'php'); - if (in_array($extension, $_supportedImageTypes)) { - $imagedata = getimagesize($src); - $imagetype = image_type_to_mime_type($imagedata[2]); - $imageext = image_type_to_extension($imagedata[2]); - $imageext = str_replace('.', '', $imageext); - if ($imageext == 'jpeg') $imageext = 'jpg'; - - if (!in_array($imagetype, $this->_imageTypes)) { - $this->_imageTypes[$imageext] = $imagetype; + if (isset($extension)) { + $imageData = getimagesize($src); + $imageType = image_type_to_mime_type($imageData[2]); + $imageExtension = str_replace('.', '', image_type_to_extension($imageData[2])); + if ($imageExtension === 'jpeg') { + $imageExtension = 'jpg'; + } + if (!in_array($imageType, $this->_imageTypes)) { + $this->_imageTypes[$imageExtension] = $imageType; } } else { if (!in_array($extension, $this->_objectTypes)) { @@ -239,10 +283,10 @@ private function _addFileToPackage($objZip, $element) $objZip->addFromString('word/' . $element['target'], $imageContents); imagedestroy($image); - $this->_chkContentTypes($element['source']); + $this->checkContentTypes($element['source']); } else { $objZip->addFile($element['source'], 'word/' . $element['target']); - $this->_chkContentTypes($element['source']); + $this->checkContentTypes($element['source']); } } -} \ No newline at end of file +} diff --git a/Classes/PHPWord/Writer/Word2007/Base.php b/Classes/PHPWord/Writer/Word2007/Base.php index 3d46444979..4bb8908db3 100755 --- a/Classes/PHPWord/Writer/Word2007/Base.php +++ b/Classes/PHPWord/Writer/Word2007/Base.php @@ -1,4 +1,5 @@ getFontStyle(); @@ -81,6 +85,9 @@ protected function _writeText(PHPWord_Shared_XMLWriter $objWriter = null, PHPWor } } + /** + * Write text run + */ protected function _writeTextRun(PHPWord_Shared_XMLWriter $objWriter = null, PHPWord_Section_TextRun $textrun) { $elements = $textrun->getElements(); @@ -106,6 +113,12 @@ protected function _writeTextRun(PHPWord_Shared_XMLWriter $objWriter = null, PHP $this->_writeText($objWriter, $element, true); } elseif ($element instanceof PHPWord_Section_Link) { $this->_writeLink($objWriter, $element, true); + } elseif ($element instanceof PHPWord_Section_Image) { + $this->_writeImage($objWriter, $element, true); + } elseif ($element instanceof PHPWord_Section_Footnote) { + $this->_writeFootnoteReference($objWriter, $element, true); + } elseif ($element instanceof PHPWord_Section_TextBreak) { + $objWriter->writeElement('w:br'); } } } @@ -113,34 +126,63 @@ protected function _writeTextRun(PHPWord_Shared_XMLWriter $objWriter = null, PHP $objWriter->endElement(); } - protected function _writeParagraphStyle(PHPWord_Shared_XMLWriter $objWriter = null, PHPWord_Style_Paragraph $style, $withoutPPR = false) - { + /** + * Write paragraph style + * + * @param PHPWord_Shared_XMLWriter $objWriter + * @param PHPWord_Style_Paragraph $style + * @param bool $withoutPPR + * @return void + */ + protected function _writeParagraphStyle( + PHPWord_Shared_XMLWriter $objWriter = null, + PHPWord_Style_Paragraph $style, + $withoutPPR = false + ) { + $align = $style->getAlign(); + $spacing = $style->getSpacing(); $spaceBefore = $style->getSpaceBefore(); $spaceAfter = $style->getSpaceAfter(); - $spacing = $style->getSpacing(); $indent = $style->getIndent(); + $hanging = $style->getHanging(); $tabs = $style->getTabs(); - - if (!is_null($align) || !is_null($spacing) || !is_null($spaceBefore) || !is_null($spaceAfter) || !is_null($indent) || !is_null($tabs)) { + $widowControl = $style->getWidowControl(); + $keepNext = $style->getKeepNext(); + $keepLines = $style->getKeepLines(); + $pageBreakBefore = $style->getPageBreakBefore(); + + if (!is_null($align) || !is_null($spacing) || !is_null($spaceBefore) || + !is_null($spaceAfter) || !is_null($indent) || !is_null($hanging) || + !is_null($tabs) || !is_null($widowControl) || !is_null($keepNext) || + !is_null($keepLines) || !is_null($pageBreakBefore)) { if (!$withoutPPR) { $objWriter->startElement('w:pPr'); } + // Alignment if (!is_null($align)) { $objWriter->startElement('w:jc'); $objWriter->writeAttribute('w:val', $align); $objWriter->endElement(); } - if (!is_null($indent)) { + // Indentation + if (!is_null($indent) || !is_null($hanging)) { $objWriter->startElement('w:ind'); $objWriter->writeAttribute('w:firstLine', 0); - $objWriter->writeAttribute('w:left', $indent); + if (!is_null($indent)) { + $objWriter->writeAttribute('w:left', $indent); + } + if (!is_null($hanging)) { + $objWriter->writeAttribute('w:hanging', $hanging); + } $objWriter->endElement(); } - if (!is_null($spaceBefore) || !is_null($spaceAfter) || !is_null($spacing)) { + // Spacing + if (!is_null($spaceBefore) || !is_null($spaceAfter) || + !is_null($spacing)) { $objWriter->startElement('w:spacing'); if (!is_null($spaceBefore)) { $objWriter->writeAttribute('w:before', $spaceBefore); @@ -155,6 +197,29 @@ protected function _writeParagraphStyle(PHPWord_Shared_XMLWriter $objWriter = nu $objWriter->endElement(); } + // Pagination + if (!$widowControl) { + $objWriter->startElement('w:widowControl'); + $objWriter->writeAttribute('w:val', '0'); + $objWriter->endElement(); + } + if ($keepNext) { + $objWriter->startElement('w:keepNext'); + $objWriter->writeAttribute('w:val', '1'); + $objWriter->endElement(); + } + if ($keepLines) { + $objWriter->startElement('w:keepLines'); + $objWriter->writeAttribute('w:val', '1'); + $objWriter->endElement(); + } + if ($pageBreakBefore) { + $objWriter->startElement('w:pageBreakBefore'); + $objWriter->writeAttribute('w:val', '1'); + $objWriter->endElement(); + } + + // Tabs if (!is_null($tabs)) { $tabs->toXml($objWriter); } @@ -165,6 +230,9 @@ protected function _writeParagraphStyle(PHPWord_Shared_XMLWriter $objWriter = nu } } + /** + * Write link + */ protected function _writeLink(PHPWord_Shared_XMLWriter $objWriter = null, PHPWord_Section_Link $link, $withoutP = false) { $rID = $link->getRelationId(); @@ -221,6 +289,9 @@ protected function _writeLink(PHPWord_Shared_XMLWriter $objWriter = null, PHPWor } } + /** + * Write preserve text + */ protected function _writePreserveText(PHPWord_Shared_XMLWriter $objWriter = null, PHPWord_Section_Footer_PreserveText $textrun) { $styleFont = $textrun->getFontStyle(); @@ -230,6 +301,9 @@ protected function _writePreserveText(PHPWord_Shared_XMLWriter $objWriter = null $SpIsObject = ($styleParagraph instanceof PHPWord_Style_Paragraph) ? true : false; $arrText = $textrun->getText(); + if (!is_array($arrText)) { + $arrText = array($arrText); + } $objWriter->startElement('w:p'); @@ -310,6 +384,9 @@ protected function _writePreserveText(PHPWord_Shared_XMLWriter $objWriter = null $objWriter->endElement(); // p } + /** + * Write text style + */ protected function _writeTextStyle(PHPWord_Shared_XMLWriter $objWriter = null, PHPWord_Style_Font $style) { $font = $style->getName(); @@ -318,34 +395,43 @@ protected function _writeTextStyle(PHPWord_Shared_XMLWriter $objWriter = null, P $color = $style->getColor(); $size = $style->getSize(); $fgColor = $style->getFgColor(); - $striketrough = $style->getStrikethrough(); + $strikethrough = $style->getStrikethrough(); $underline = $style->getUnderline(); + $superscript = $style->getSuperScript(); + $subscript = $style->getSubScript(); + $hint = $style->getHint(); $objWriter->startElement('w:rPr'); // Font - if ($font != 'Arial') { + if ($font != PHPWord::DEFAULT_FONT_NAME) { $objWriter->startElement('w:rFonts'); $objWriter->writeAttribute('w:ascii', $font); $objWriter->writeAttribute('w:hAnsi', $font); + $objWriter->writeAttribute('w:eastAsia', $font); $objWriter->writeAttribute('w:cs', $font); + //Font Content Type + if ($hint != PHPWord::DEFAULT_FONT_CONTENT_TYPE) { + $objWriter->writeAttribute('w:hint', $hint); + } $objWriter->endElement(); } + // Color - if ($color != '000000') { + if ($color != PHPWord::DEFAULT_FONT_COLOR) { $objWriter->startElement('w:color'); $objWriter->writeAttribute('w:val', $color); $objWriter->endElement(); } // Size - if ($size != 20) { + if ($size != PHPWord::DEFAULT_FONT_SIZE) { $objWriter->startElement('w:sz'); - $objWriter->writeAttribute('w:val', $size); + $objWriter->writeAttribute('w:val', $size * 2); $objWriter->endElement(); $objWriter->startElement('w:szCs'); - $objWriter->writeAttribute('w:val', $size); + $objWriter->writeAttribute('w:val', $size * 2); $objWriter->endElement(); } @@ -367,8 +453,8 @@ protected function _writeTextStyle(PHPWord_Shared_XMLWriter $objWriter = null, P $objWriter->endElement(); } - // Striketrough - if ($striketrough) { + // Strikethrough + if ($strikethrough) { $objWriter->writeElement('w:strike', null); } @@ -379,14 +465,68 @@ protected function _writeTextStyle(PHPWord_Shared_XMLWriter $objWriter = null, P $objWriter->endElement(); } + // Superscript/subscript + if ($superscript || $subscript) { + $objWriter->startElement('w:vertAlign'); + $objWriter->writeAttribute('w:val', $superscript ? 'superscript' : 'subscript'); + $objWriter->endElement(); + } + $objWriter->endElement(); } - protected function _writeTextBreak(PHPWord_Shared_XMLWriter $objWriter = null) + /** + * Write text break + * + * @param PHPWord_Shared_XMLWriter $objWriter + * @param PHPWord_Section_TextBreak $element + */ + protected function _writeTextBreak($objWriter, $element = null) { - $objWriter->writeElement('w:p', null); + $hasStyle = false; + if (!is_null($element)) { + $fontStyle = $element->getFontStyle(); + $sfIsObject = ($fontStyle instanceof PHPWord_Style_Font) ? true : false; + $paragraphStyle = $element->getParagraphStyle(); + $spIsObject = ($paragraphStyle instanceof PHPWord_Style_Paragraph) ? true : false; + $hasStyle = !is_null($fontStyle) || !is_null($paragraphStyle); + } + if ($hasStyle) { + // Paragraph style + $objWriter->startElement('w:p'); + if ($spIsObject) { + $this->_writeParagraphStyle($objWriter, $paragraphStyle); + } elseif (!$spIsObject && !is_null($paragraphStyle)) { + $objWriter->startElement('w:pPr'); + $objWriter->startElement('w:pStyle'); + $objWriter->writeAttribute('w:val', $paragraphStyle); + $objWriter->endElement(); // w:pStyle + $objWriter->endElement(); // w:pPr + } + // Font style + if (!is_null($fontStyle)) { + $objWriter->startElement('w:pPr'); + if ($sfIsObject) { + $this->_writeTextStyle($objWriter, $fontStyle); + } elseif (!$sfIsObject && !is_null($fontStyle)) { + $objWriter->startElement('w:rPr'); + $objWriter->startElement('w:rStyle'); + $objWriter->writeAttribute('w:val', $fontStyle); + $objWriter->endElement(); // w:rStyle + $objWriter->endElement(); // w:rPr + } + $objWriter->endElement(); // w:pPr + } + $objWriter->endElement(); // w:p + } else { + // Null element. No paragraph nor font style + $objWriter->writeElement('w:p', null); + } } + /** + * Write table + */ protected function _writeTable(PHPWord_Shared_XMLWriter $objWriter = null, PHPWord_Section_Table $table) { $_rows = $table->getRows(); @@ -395,6 +535,7 @@ protected function _writeTable(PHPWord_Shared_XMLWriter $objWriter = null, PHPWo if ($_cRows > 0) { $objWriter->startElement('w:tbl'); $tblStyle = $table->getStyle(); + $tblWidth = $table->getWidth(); if ($tblStyle instanceof PHPWord_Style_Table) { $this->_writeTableStyle($objWriter, $tblStyle); } else { @@ -403,26 +544,46 @@ protected function _writeTable(PHPWord_Shared_XMLWriter $objWriter = null, PHPWo $objWriter->startElement('w:tblStyle'); $objWriter->writeAttribute('w:val', $tblStyle); $objWriter->endElement(); + if (!is_null($tblWidth)) { + $objWriter->startElement('w:tblW'); + $objWriter->writeAttribute('w:w', $tblWidth); + $objWriter->writeAttribute('w:type', 'pct'); + $objWriter->endElement(); + } $objWriter->endElement(); } } - $_heights = $table->getRowHeights(); for ($i = 0; $i < $_cRows; $i++) { $row = $_rows[$i]; - $height = $_heights[$i]; + $height = $row->getHeight(); + $rowStyle = $row->getStyle(); + $tblHeader = $rowStyle->getTblHeader(); + $cantSplit = $rowStyle->getCantSplit(); $objWriter->startElement('w:tr'); - if (!is_null($height)) { + if (!is_null($height) || !is_null($tblHeader) || !is_null($cantSplit)) { $objWriter->startElement('w:trPr'); - $objWriter->startElement('w:trHeight'); - $objWriter->writeAttribute('w:val', $height); - $objWriter->endElement(); + if (!is_null($height)) { + $objWriter->startElement('w:trHeight'); + $objWriter->writeAttribute('w:val', $height); + $objWriter->endElement(); + } + if ($tblHeader) { + $objWriter->startElement('w:tblHeader'); + $objWriter->writeAttribute('w:val', '1'); + $objWriter->endElement(); + } + if ($cantSplit) { + $objWriter->startElement('w:cantSplit'); + $objWriter->writeAttribute('w:val', '1'); + $objWriter->endElement(); + } $objWriter->endElement(); } - foreach ($row as $cell) { + foreach ($row->getCells() as $cell) { $objWriter->startElement('w:tc'); $cellStyle = $cell->getStyle(); @@ -450,11 +611,11 @@ protected function _writeTable(PHPWord_Shared_XMLWriter $objWriter = null, PHPWo } elseif ($element instanceof PHPWord_Section_Link) { $this->_writeLink($objWriter, $element); } elseif ($element instanceof PHPWord_Section_TextBreak) { - $this->_writeTextBreak($objWriter); + $this->_writeTextBreak($objWriter, $element); } elseif ($element instanceof PHPWord_Section_ListItem) { $this->_writeListItem($objWriter, $element); } elseif ($element instanceof PHPWord_Section_Image || - $element instanceof PHPWord_Section_MemoryImage + $element instanceof PHPWord_Section_MemoryImage ) { $this->_writeImage($objWriter, $element); } elseif ($element instanceof PHPWord_Section_Object) { @@ -475,6 +636,9 @@ protected function _writeTable(PHPWord_Shared_XMLWriter $objWriter = null, PHPWo } } + /** + * Write table style + */ protected function _writeTableStyle(PHPWord_Shared_XMLWriter $objWriter = null, PHPWord_Style_Table $style = null) { $margins = $style->getCellMargin(); @@ -520,6 +684,9 @@ protected function _writeTableStyle(PHPWord_Shared_XMLWriter $objWriter = null, } } + /** + * Write cell style + */ protected function _writeCellStyle(PHPWord_Shared_XMLWriter $objWriter = null, PHPWord_Style_Cell $style = null) { $bgColor = $style->getBgColor(); @@ -625,9 +792,9 @@ protected function _writeCellStyle(PHPWord_Shared_XMLWriter $objWriter = null, P /** * @param \PHPWord_Shared_XMLWriter $objWriter - * @param \PHPWord_Section_Image $image + * @param \PHPWord_Section_Image|\PHPWord_Section_MemoryImage $image */ - protected function _writeImage(PHPWord_Shared_XMLWriter $objWriter = null, PHPWord_Section_Image $image) + protected function _writeImage(PHPWord_Shared_XMLWriter $objWriter = null, $image, $withoutP = false) { $rId = $image->getRelationId(); @@ -639,14 +806,16 @@ protected function _writeImage(PHPWord_Shared_XMLWriter $objWriter = null, PHPWo $marginLeft = $style->getMarginLeft(); $wrappingStyle = $style->getWrappingStyle(); - $objWriter->startElement('w:p'); + if (!$withoutP) { + $objWriter->startElement('w:p'); - if (!is_null($align)) { - $objWriter->startElement('w:pPr'); - $objWriter->startElement('w:jc'); - $objWriter->writeAttribute('w:val', $align); - $objWriter->endElement(); - $objWriter->endElement(); + if (!is_null($align)) { + $objWriter->startElement('w:pPr'); + $objWriter->startElement('w:jc'); + $objWriter->writeAttribute('w:val', $align); + $objWriter->endElement(); + $objWriter->endElement(); + } } $objWriter->startElement('w:r'); @@ -697,9 +866,14 @@ protected function _writeImage(PHPWord_Shared_XMLWriter $objWriter = null, PHPWo $objWriter->endElement(); - $objWriter->endElement(); + if (!$withoutP) { + $objWriter->endElement(); // w:p + } } + /** + * Write watermark + */ protected function _writeWatermark(PHPWord_Shared_XMLWriter $objWriter = null, $image) { $rId = $image->getRelationId(); @@ -744,6 +918,9 @@ protected function _writeWatermark(PHPWord_Shared_XMLWriter $objWriter = null, $ $objWriter->endElement(); } + /** + * Write title + */ protected function _writeTitle(PHPWord_Shared_XMLWriter $objWriter = null, PHPWord_Section_Title $title) { $text = htmlspecialchars($title->getText()); @@ -785,4 +962,64 @@ protected function _writeTitle(PHPWord_Shared_XMLWriter $objWriter = null, PHPWo $objWriter->endElement(); } -} \ No newline at end of file + + /** + * Write footnote + */ + protected function _writeFootnote(PHPWord_Shared_XMLWriter $objWriter = null, PHPWord_Section_Footnote $footnote) + { + $objWriter->startElement('w:footnote'); + $objWriter->writeAttribute('w:id', $footnote->getReferenceId()); + + $styleParagraph = $footnote->getParagraphStyle(); + $SpIsObject = ($styleParagraph instanceof PHPWord_Style_Paragraph) ? true : false; + + $objWriter->startElement('w:p'); + + if ($SpIsObject) { + $this->_writeParagraphStyle($objWriter, $styleParagraph); + } elseif (!$SpIsObject && !is_null($styleParagraph)) { + $objWriter->startElement('w:pPr'); + $objWriter->startElement('w:pStyle'); + $objWriter->writeAttribute('w:val', $styleParagraph); + $objWriter->endElement(); + $objWriter->endElement(); + } + + $elements = $footnote->getElements(); + if (count($elements) > 0) { + foreach ($elements as $element) { + if ($element instanceof PHPWord_Section_Text) { + $this->_writeText($objWriter, $element, true); + } elseif ($element instanceof PHPWord_Section_Link) { + $this->_writeLink($objWriter, $element, true); + } + } + } + + $objWriter->endElement(); // w:p + $objWriter->endElement(); // w:footnote + } + + /** + * Write footnote reference + */ + protected function _writeFootnoteReference(PHPWord_Shared_XMLWriter $objWriter = null, PHPWord_Section_Footnote $footnote, $withoutP = false) + { + if (!$withoutP) { + $objWriter->startElement('w:p'); + } + + $objWriter->startElement('w:r'); + + $objWriter->startElement('w:footnoteReference'); + $objWriter->writeAttribute('w:id', $footnote->getReferenceId()); + $objWriter->endElement(); // w:footnoteReference + + $objWriter->endElement(); // w:r + + if (!$withoutP) { + $objWriter->endElement(); // w:p + } + } +} diff --git a/Classes/PHPWord/Writer/Word2007/ContentTypes.php b/Classes/PHPWord/Writer/Word2007/ContentTypes.php index 0c8da192e9..eeaeb84dba 100755 --- a/Classes/PHPWord/Writer/Word2007/ContentTypes.php +++ b/Classes/PHPWord/Writer/Word2007/ContentTypes.php @@ -31,7 +31,7 @@ class PHPWord_Writer_Word2007_ContentTypes extends PHPWord_Writer_Word2007_WriterPart { - public function writeContentTypes($_imageTypes, $_objectTypes, $_cHdrs, $_cFtrs) + public function writeContentTypes($_imageTypes, $_objectTypes, $_cHdrs, $footers) { // Create XML writer $objWriter = null; @@ -50,12 +50,16 @@ public function writeContentTypes($_imageTypes, $_objectTypes, $_cHdrs, $_cFtrs) // Rels $this->_writeDefaultContentType( - $objWriter, 'rels', 'application/vnd.openxmlformats-package.relationships+xml' + $objWriter, + 'rels', + 'application/vnd.openxmlformats-package.relationships+xml' ); // XML $this->_writeDefaultContentType( - $objWriter, 'xml', 'application/xml' + $objWriter, + 'xml', + 'application/xml' ); // Add media content-types @@ -65,63 +69,98 @@ public function writeContentTypes($_imageTypes, $_objectTypes, $_cHdrs, $_cFtrs) // Add embedding content-types if (count($_objectTypes) > 0) { - $this->_writeDefaultContentType($objWriter, 'bin', 'application/vnd.openxmlformats-officedocument.oleObject'); + $this->_writeDefaultContentType( + $objWriter, + 'bin', + 'application/vnd.openxmlformats-officedocument.oleObject' + ); } // DocProps $this->_writeOverrideContentType( - $objWriter, '/docProps/app.xml', 'application/vnd.openxmlformats-officedocument.extended-properties+xml' + $objWriter, + '/docProps/app.xml', + 'application/vnd.openxmlformats-officedocument.extended-properties+xml' ); $this->_writeOverrideContentType( - $objWriter, '/docProps/core.xml', 'application/vnd.openxmlformats-package.core-properties+xml' + $objWriter, + '/docProps/core.xml', + 'application/vnd.openxmlformats-package.core-properties+xml' ); // Document $this->_writeOverrideContentType( - $objWriter, '/word/document.xml', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml' + $objWriter, + '/word/document.xml', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml' ); // Styles $this->_writeOverrideContentType( - $objWriter, '/word/styles.xml', 'application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml' + $objWriter, + '/word/styles.xml', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml' ); // Numbering $this->_writeOverrideContentType( - $objWriter, '/word/numbering.xml', 'application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml' + $objWriter, + '/word/numbering.xml', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml' ); // Settings $this->_writeOverrideContentType( - $objWriter, '/word/settings.xml', 'application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml' + $objWriter, + '/word/settings.xml', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml' ); // Theme1 $this->_writeOverrideContentType( - $objWriter, '/word/theme/theme1.xml', 'application/vnd.openxmlformats-officedocument.theme+xml' + $objWriter, + '/word/theme/theme1.xml', + 'application/vnd.openxmlformats-officedocument.theme+xml' ); // WebSettings $this->_writeOverrideContentType( - $objWriter, '/word/webSettings.xml', 'application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml' + $objWriter, + '/word/webSettings.xml', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml' ); // Font Table $this->_writeOverrideContentType( - $objWriter, '/word/fontTable.xml', 'application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml' + $objWriter, + '/word/fontTable.xml', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml' + ); + + // Footnotes + $this->_writeOverrideContentType( + $objWriter, + '/word/footnotes.xml', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml' ); for ($i = 1; $i <= $_cHdrs; $i++) { $this->_writeOverrideContentType( - $objWriter, '/word/header' . $i . '.xml', 'application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml' + $objWriter, + '/word/header' . $i . '.xml', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml' ); } - for ($i = 1; $i <= $_cFtrs; $i++) { - $this->_writeOverrideContentType( - $objWriter, '/word/footer' . $i . '.xml', 'application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml' - ); + for ($i = 1; $i <= count($footers); $i++) { + if (!is_null($footers[$i])) { + $this->_writeOverrideContentType( + $objWriter, + '/word/footer' . $i . '.xml', + 'application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml' + ); + } } @@ -172,7 +211,7 @@ private function _writeDefaultContentType(PHPWord_Shared_XMLWriter $objWriter = /** * Write Override content type * - * @param PHPPowerPoint_Shared_XMLWriter $objWriter XML Writer + * @param PHPWord_Shared_XMLWriter $objWriter XML Writer * @param string $pPartname Part name * @param string $pContentType Content type * @throws Exception diff --git a/Classes/PHPWord/Writer/Word2007/Document.php b/Classes/PHPWord/Writer/Word2007/Document.php index 41718f6e64..9991179d5c 100755 --- a/Classes/PHPWord/Writer/Word2007/Document.php +++ b/Classes/PHPWord/Writer/Word2007/Document.php @@ -79,7 +79,7 @@ public function writeDocument(PHPWord $pPHPWord = null) } elseif ($element instanceof PHPWord_Section_Title) { $this->_writeTitle($objWriter, $element); } elseif ($element instanceof PHPWord_Section_TextBreak) { - $this->_writeTextBreak($objWriter); + $this->_writeTextBreak($objWriter, $element); } elseif ($element instanceof PHPWord_Section_PageBreak) { $this->_writePageBreak($objWriter); } elseif ($element instanceof PHPWord_Section_Table) { @@ -94,6 +94,8 @@ public function writeDocument(PHPWord $pPHPWord = null) $this->_writeObject($objWriter, $element); } elseif ($element instanceof PHPWord_TOC) { $this->_writeTOC($objWriter); + } elseif ($element instanceof PHPWord_Section_Footnote) { + $this->_writeFootnoteReference($objWriter, $element); } } @@ -135,8 +137,15 @@ private function _writeEndSection(PHPWord_Shared_XMLWriter $objWriter = null, PH $marginRight = $settings->getMarginRight(); $marginBottom = $settings->getMarginBottom(); + $headerHeight = $settings->getHeaderHeight(); + $footerHeight = $settings->getFooterHeight(); + $borders = $settings->getBorderSize(); + $colsNum = $settings->getColsNum(); + $colsSpace = $settings->getColsSpace(); + $breakType = $settings->getBreakType(); + $objWriter->startElement('w:sectPr'); foreach ($_headers as &$_header) { @@ -152,6 +161,12 @@ private function _writeEndSection(PHPWord_Shared_XMLWriter $objWriter = null, PH $objWriter->endElement(); } + if (!is_null($breakType)) { + $objWriter->startElement('w:type'); + $objWriter->writeAttribute('w:val', $breakType); + $objWriter->endElement(); + } + if (!is_null($_footer)) { $rId = $_footer->getRelationId(); $objWriter->startElement('w:footerReference'); @@ -175,8 +190,8 @@ private function _writeEndSection(PHPWord_Shared_XMLWriter $objWriter = null, PH $objWriter->writeAttribute('w:right', $marginRight); $objWriter->writeAttribute('w:bottom', $marginBottom); $objWriter->writeAttribute('w:left', $marginLeft); - $objWriter->writeAttribute('w:header', '720'); - $objWriter->writeAttribute('w:footer', '720'); + $objWriter->writeAttribute('w:header', $headerHeight); + $objWriter->writeAttribute('w:footer', $footerHeight); $objWriter->writeAttribute('w:gutter', '0'); $objWriter->endElement(); @@ -233,7 +248,8 @@ private function _writeEndSection(PHPWord_Shared_XMLWriter $objWriter = null, PH } $objWriter->startElement('w:cols'); - $objWriter->writeAttribute('w:space', '720'); + $objWriter->writeAttribute('w:num', $colsNum); + $objWriter->writeAttribute('w:space', $colsSpace); $objWriter->endElement(); diff --git a/Classes/PHPWord/Writer/Word2007/Footer.php b/Classes/PHPWord/Writer/Word2007/Footer.php index 1cd49771cb..f9b4763e5f 100755 --- a/Classes/PHPWord/Writer/Word2007/Footer.php +++ b/Classes/PHPWord/Writer/Word2007/Footer.php @@ -63,7 +63,7 @@ public function writeFooter(PHPWord_Section_Footer $footer) } elseif ($element instanceof PHPWord_Section_TextRun) { $this->_writeTextRun($objWriter, $element); } elseif ($element instanceof PHPWord_Section_TextBreak) { - $this->_writeTextBreak($objWriter); + $this->_writeTextBreak($objWriter, $element); } elseif ($element instanceof PHPWord_Section_Table) { $this->_writeTable($objWriter, $element); } elseif ($element instanceof PHPWord_Section_Image || diff --git a/Classes/PHPWord/Writer/Word2007/Footnotes.php b/Classes/PHPWord/Writer/Word2007/Footnotes.php new file mode 100644 index 0000000000..fe7ced0ed9 --- /dev/null +++ b/Classes/PHPWord/Writer/Word2007/Footnotes.php @@ -0,0 +1,83 @@ +getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPWord_Shared_XMLWriter(PHPWord_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPWord_Shared_XMLWriter(PHPWord_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0', 'UTF-8', 'yes'); + + $objWriter->startElement('w:footnotes'); + $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); + $objWriter->writeAttribute('xmlns:w', 'http://schemas.openxmlformats.org/wordprocessingml/2006/main'); + + // write separator and continuation separator + $objWriter->startElement('w:footnote'); + $objWriter->writeAttribute('w:id', 0); + $objWriter->writeAttribute('w:type', 'separator'); + $objWriter->startElement('w:p'); + $objWriter->startElement('w:r'); + $objWriter->startElement('w:separator'); + $objWriter->endElement(); // w:separator + $objWriter->endElement(); // w:r + $objWriter->endElement(); // w:p + $objWriter->endElement(); // w:footnote + + $objWriter->startElement('w:footnote'); + $objWriter->writeAttribute('w:id', 1); + $objWriter->writeAttribute('w:type', 'continuationSeparator'); + $objWriter->startElement('w:p'); + $objWriter->startElement('w:r'); + $objWriter->startElement('w:continuationSeparator'); + $objWriter->endElement(); // w:continuationSeparator + $objWriter->endElement(); // w:r + $objWriter->endElement(); // w:p + $objWriter->endElement(); // w:footnote + + + foreach ($allFootnotesCollection as $footnote) { + if ($footnote instanceof PHPWord_Section_Footnote) { + $this->_writeFootnote($objWriter, $footnote); + } + } + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } +} diff --git a/Classes/PHPWord/Writer/Word2007/FootnotesRels.php b/Classes/PHPWord/Writer/Word2007/FootnotesRels.php new file mode 100644 index 0000000000..6c81b3c95e --- /dev/null +++ b/Classes/PHPWord/Writer/Word2007/FootnotesRels.php @@ -0,0 +1,86 @@ +getParentWriter()->getUseDiskCaching()) { + $objWriter = new PHPWord_Shared_XMLWriter(PHPWord_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new PHPWord_Shared_XMLWriter(PHPWord_Shared_XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0', 'UTF-8', 'yes'); + + // Relationships + $objWriter->startElement('Relationships'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships'); + + // Relationships to Links + foreach ($_relsCollection as $relation) { + $relationType = $relation['type']; + $relationName = $relation['target']; + $relationId = $relation['rID']; + $targetMode = ($relationType == 'hyperlink') ? 'External' : ''; + + $this->_writeRelationship($objWriter, $relationId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/' . $relationType, $relationName, $targetMode); + } + + $objWriter->endElement(); + + // Return + return $objWriter->getData(); + } + + private function _writeRelationship(PHPWord_Shared_XMLWriter $objWriter = null, $pId = 1, $pType = '', $pTarget = '', $pTargetMode = '') + { + if ($pType != '' && $pTarget != '') { + if (strpos($pId, 'rId') === false) { + $pId = 'rId' . $pId; + } + + // Write relationship + $objWriter->startElement('Relationship'); + $objWriter->writeAttribute('Id', $pId); + $objWriter->writeAttribute('Type', $pType); + $objWriter->writeAttribute('Target', $pTarget); + + if ($pTargetMode != '') { + $objWriter->writeAttribute('TargetMode', $pTargetMode); + } + + $objWriter->endElement(); + } else { + throw new Exception("Invalid parameters passed."); + } + } +} diff --git a/Classes/PHPWord/Writer/Word2007/Header.php b/Classes/PHPWord/Writer/Word2007/Header.php index 4106d197c3..6bb6f7844e 100755 --- a/Classes/PHPWord/Writer/Word2007/Header.php +++ b/Classes/PHPWord/Writer/Word2007/Header.php @@ -63,7 +63,7 @@ public function writeHeader(PHPWord_Section_Header $header) } elseif ($element instanceof PHPWord_Section_TextRun) { $this->_writeTextRun($objWriter, $element); } elseif ($element instanceof PHPWord_Section_TextBreak) { - $this->_writeTextBreak($objWriter); + $this->_writeTextBreak($objWriter, $element); } elseif ($element instanceof PHPWord_Section_Table) { $this->_writeTable($objWriter, $element); } elseif ($element instanceof PHPWord_Section_Image || diff --git a/Classes/PHPWord/Writer/Word2007/Styles.php b/Classes/PHPWord/Writer/Word2007/Styles.php index d2e285390b..c87d94bfa2 100755 --- a/Classes/PHPWord/Writer/Word2007/Styles.php +++ b/Classes/PHPWord/Writer/Word2007/Styles.php @@ -59,8 +59,30 @@ public function writeStyles(PHPWord $pPHPWord = null) // Write Style Definitions $styles = PHPWord_Style::getStyles(); + + // Write normal paragraph style + $normalStyle = null; + if (array_key_exists('Normal', $styles)) { + $normalStyle = $styles['Normal']; + } + $objWriter->startElement('w:style'); + $objWriter->writeAttribute('w:type', 'paragraph'); + $objWriter->writeAttribute('w:default', '1'); + $objWriter->writeAttribute('w:styleId', 'Normal'); + $objWriter->startElement('w:name'); + $objWriter->writeAttribute('w:val', 'Normal'); + $objWriter->endElement(); + if (!is_null($normalStyle)) { + $this->_writeParagraphStyle($objWriter, $normalStyle); + } + $objWriter->endElement(); + + // Write other styles if (count($styles) > 0) { foreach ($styles as $styleName => $style) { + if ($styleName == 'Normal') { + continue; + } if ($style instanceof PHPWord_Style_Font) { $paragraphStyle = $style->getParagraphStyle(); @@ -92,6 +114,10 @@ public function writeStyles(PHPWord $pPHPWord = null) $objWriter->endElement(); if (!is_null($paragraphStyle)) { + // Point parent style to Normal + $objWriter->startElement('w:basedOn'); + $objWriter->writeAttribute('w:val', 'Normal'); + $objWriter->endElement(); $this->_writeParagraphStyle($objWriter, $paragraphStyle); } @@ -109,6 +135,22 @@ public function writeStyles(PHPWord $pPHPWord = null) $objWriter->writeAttribute('w:val', $styleName); $objWriter->endElement(); + // Parent style + $basedOn = $style->getBasedOn(); + if (!is_null($basedOn)) { + $objWriter->startElement('w:basedOn'); + $objWriter->writeAttribute('w:val', $basedOn); + $objWriter->endElement(); + } + + // Next paragraph style + $next = $style->getNext(); + if (!is_null($next)) { + $objWriter->startElement('w:next'); + $objWriter->writeAttribute('w:val', $next); + $objWriter->endElement(); + } + $this->_writeParagraphStyle($objWriter, $style); $objWriter->endElement(); @@ -338,11 +380,11 @@ private function _writeDocDefaults(PHPWord_Shared_XMLWriter $objWriter = null) $objWriter->endElement(); $objWriter->startElement('w:sz'); - $objWriter->writeAttribute('w:val', $fontSize); + $objWriter->writeAttribute('w:val', $fontSize * 2); $objWriter->endElement(); $objWriter->startElement('w:szCs'); - $objWriter->writeAttribute('w:val', $fontSize); + $objWriter->writeAttribute('w:val', $fontSize * 2); $objWriter->endElement(); $objWriter->endElement(); diff --git a/README.md b/README.md index dc1a611a68..d35603d048 100755 --- a/README.md +++ b/README.md @@ -5,16 +5,43 @@ __OpenXML - Read, Write and Create Word documents in PHP.__ -PHPWord is a library written in PHP that create word documents. +PHPWord is a library written in pure PHP and providing a set of classes that allow you to write to and read from different document file formats, like Word (.docx), WordPad (.rtf), Libre/OpenOffice Writer (.odt). -No Windows operating system is needed for usage because the result are docx files (Office Open XML) that can be -opened by all major office software. +No Windows operating system is needed for usage because the resulting DOCX, ODT, or RTF files can be opened by all major [word processing softwares](http://en.wikipedia.org/wiki/List_of_word_processors). + +PHPWord is an open source project licensed under [LGPL](license.md). PHPWord is unit tested to make sure that the released versions are stable. __Want to contribute?__ Fork us! +## Features + +* Set document properties, e.g. title, subject, and creator. +* Create document sections with different settings, e.g. portrait/landscape, page size, and page numbering +* Create header and footer for each sections +* Set default font type, font size, and paragraph style +* Use UTF-8 and East Asia fonts/characters +* Define custom font styles (e.g. bold, italic, color) and paragraph styles (e.g. centered, multicolumns, spacing) either as named style or inline in text +* Insert paragraphs, either as a simple text or complex one (a text run) that contains other elements +* Insert titles (headers) and table of contents +* Insert text breaks and page breaks +* Insert and format images, either local, remote, or as page watermarks +* Insert binary OLE Objects such as Excel or Visio +* Insert and format table with customized properties for each rows (e.g. repeat as header row) and cells (e.g. background color, rowspan, colspan) +* Insert list items as bulleted, numbered, or multilevel +* Insert hyperlinks +* Create document from templates +* Use XSL 1.0 style sheets to transform main document part of OOXML template +* ... and many more features on progress + ## Requirements +* PHP 5.3+ +* PHP [Zip](http://php.net/manual/en/book.zip.php) extension +* PHP [XML Parser](http://www.php.net/manual/en/xml.installation.php) extension -* PHP version 5.3.0 or higher +## Optional PHP extensions +* [GD](http://php.net/manual/en/book.image.php) +* [XMLWriter](http://php.net/manual/en/book.xmlwriter.php) +* [XSL](http://php.net/manual/en/book.xsl.php) ## Installation @@ -31,53 +58,132 @@ the following lines to your ``composer.json``. ## Documentation +We're reorganizing our documentation. Below are some of the most important things that you needed to get PHPWord creates document for you in no time. + ### Table of contents 1. [Basic usage](#basic-usage) + * [Measurement units](#measurement-units) 2. [Sections](#sections) - * [Change Section Page Numbering](#sections-page-numbering) -3. [Tables](#tables) + * [Section settings](#section-settings) + * [Section page numbering](#section-page-numbering) +3. [Texts](#texts) + * [Attributes](#text-attributes) +4. [Paragraph Style](#paragraph-style) + * [Attributes](#paragraph-style-attributes) +5. [Tables](#tables) * [Cell Style](#tables-cell-style) -4. [Images](#images) +6. [Images](#images) + * [Attributes](#images-attributes) #### Basic usage -The following is a basic example of the PHPWord library. +The following is a basic example of the PHPWord library. More examples are provided in the [samples folder](samples/). ```php $PHPWord = new PHPWord(); -// Every element you want to append to the word document is placed in a section. So you need a section: +// Every element you want to append to the word document is placed in a section. +// To create a basic section: $section = $PHPWord->createSection(); // After creating a section, you can append elements: $section->addText('Hello world!'); // You can directly style your text by giving the addText function an array: -$section->addText('Hello world! I am formatted.', array('name'=>'Tahoma', 'size'=>16, 'bold'=>true)); - -// If you often need the same style again you can create a user defined style to the word document -// and give the addText function the name of the style: -$PHPWord->addFontStyle('myOwnStyle', array('name'=>'Verdana', 'size'=>14, 'color'=>'1B2232')); -$section->addText('Hello world! I am formatted by a user defined style', 'myOwnStyle'); - -// You can also putthe appended element to local object an call functions like this: +$section->addText('Hello world! I am formatted.', + array('name'=>'Tahoma', 'size'=>16, 'bold'=>true)); + +// If you often need the same style again you can create a user defined style +// to the word document and give the addText function the name of the style: +$PHPWord->addFontStyle('myOwnStyle', + array('name'=>'Verdana', 'size'=>14, 'color'=>'1B2232')); +$section->addText('Hello world! I am formatted by a user defined style', + 'myOwnStyle'); + +// You can also put the appended element to local object like this: +$fontStyle = new PHPWord_Style_Font(); +$fontStyle->setBold(true); +$fontStyle->setName('Verdana'); +$fontStyle->setSize(22); $myTextElement = $section->addText('Hello World!'); -$myTextElement->setBold(); -$myTextElement->setName('Verdana'); -$myTextElement->setSize(22); +$myTextElement->setFontStyle($fontStyle); -// At least write the document to webspace: +// Finally, write the document: $objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'Word2007'); $objWriter->save('helloWorld.docx'); ``` + +##### Measurement units + +The base length unit in Open Office XML is twip. Twip means "TWentieth of an Inch Point", i.e. 1 twip = 1/1440 inch. + +You can use PHPWord helper functions to convert inches, centimeters, or points to twips. + +```php +// Paragraph with 6 points space after +$PHPWord->addParagraphStyle('My Style', array( + 'spaceAfter' => PHPWord_Shared_Font::pointSizeToTwips(6)) +); + +$section = $PHPWord->createSection(); +$sectionStyle = $section->getSettings(); +// half inch left margin +$sectionStyle->setMarginLeft(PHPWord_Shared_Font::inchSizeToTwips(.5)); +// 2 cm right margin +$sectionStyle->setMarginRight(PHPWord_Shared_Font::centimeterSizeToTwips(2)); +``` + #### Sections - -##### Change Section Page Numbering +Every visible element in word is placed inside of a section. To create a section, use the following code: + +```php +$section = $PHPWord->createSection($sectionSettings); +``` +The `$sectionSettings` is an optional associative array that sets the section. Example: + +```php +$sectionSettings = array( + 'orientation' => 'landscape', + 'marginTop' => 600, + 'colsNum' => 2, +); +``` + +##### Section settings + +Below are the available settings for section: + +* `orientation` Page orientation, i.e. 'portrait' (default) or 'landscape' +* `marginTop` Page margin top in twips +* `marginLeft` Page margin left in twips +* `marginRight` Page margin right in twips +* `marginBottom` Page margin bottom in twips +* `borderTopSize` Border top size in twips +* `borderTopColor` Border top color +* `borderLeftSize` Border left size in twips +* `borderLeftColor` Border left color +* `borderRightSize` Border right size in twips +* `borderRightColor` Border right color +* `borderBottomSize` Border bottom size in twips +* `borderBottomColor` Border bottom color +* `headerHeight` Spacing to top of header +* `footerHeight` Spacing to bottom of footer +* `colsNum` Number of columns +* `colsSpace` Spacing between columns +* `breakType` Section break type (nextPage, nextColumn, continuous, evenPage, oddPage) + +The following two settings are automatically set by the use of the `orientation` setting. You can alter them but that's not recommended. + +* `pageSizeW` Page width in twips +* `pageSizeH` Page height in twips + + +##### Section page numbering You can change a section page numbering. @@ -86,6 +192,56 @@ $section = $PHPWord->createSection(); $section->getSettings()->setPageNumberingStart(1); ``` + +#### Texts + +Text can be added by using `addText` and `createTextRun` method. `addText` is used for creating simple paragraphs that only contain texts with the same style. `createTextRun` is used for creating complex paragraphs that contain text with different style (some bold, other italics, etc) or other elements, e.g. images or links. + +`addText` sample: + +```php +$fontStyle = array('name' => 'Times New Roman', 'size' => 9); +$paragraphStyle = array('align' => 'both'); +$section->addText('I am simple paragraph', $fontStyle, $paragraphStyle); +``` + +`createTextRun` sample: + +```php +$textrun = $section->createTextRun(); +$textrun->addText('I am bold', array('bold' => true)); +$textrun->addText('I am italic, array('italic' => true)); +$textrun->addText('I am colored, array('color' => 'AACC00')); +``` + + +##### Attributes + +* ``size`` text size, e.g. _20_, _22_, +* ``name`` font name, e.g. _Arial_ +* ``bold`` text is bold, _true_ or _false_ +* ``italic`` text is italic, _true_ or _false_ +* ``superScript`` text is super script, _true_ or _false_ +* ``subScript`` text is sub script, _true_ or _false_ +* ``underline`` text is underline, _true_ or _false_ +* ``strikethrough`` text is strikethrough, _true_ or _false_ +* ``color`` text color, e.g. _FF0000_ +* ``fgColor`` fgColor +* ``line-height`` text line height, e.g. _1.0_, _1.5_, ect... + + +#### Paragraph Style + + +##### Attributes + +* ``line-height`` text line height, e.g. _1.0_, _1.5_, ect... +* ``align`` paragraph alignment, _left_, _right_ or _center_ +* ``spaceBefore`` space before Paragraph +* ``spaceAfter`` space after Paragraph +* ``tabs`` set of Custom Tab Stops +* ``indent`` indent by how much + #### Tables @@ -119,7 +275,9 @@ $section = $PHPWord->createSection(); $section->addImage('mars.jpg'); ``` -Images settings include: + +##### Attributes + * ``width`` width in pixels * ``height`` height in pixels * ``align`` image alignment, _left_, _right_ or _center_ @@ -127,7 +285,7 @@ Images settings include: * ``marginLeft`` left margin in inches, can be negative * ``wrappingStyle`` can be _inline_, _square_, _tight_, _behind_, _infront_ -To add an image with settings, consider the following example. +To add an image with attributes, consider the following example. ```php $section->addImage( @@ -140,4 +298,4 @@ $section->addImage( 'wrappingStyle' => 'behind' ) ); - ``` +``` \ No newline at end of file diff --git a/Tests/PHPWord/AutoloaderTest.php b/Tests/PHPWord/AutoloaderTest.php index f24c04e8b9..03e16db073 100644 --- a/Tests/PHPWord/AutoloaderTest.php +++ b/Tests/PHPWord/AutoloaderTest.php @@ -1,11 +1,10 @@ assertNull(PHPWord_Autoloader::load('Foo'), 'PHPWord_Autoloader::load() is trying to load classes outside of the PHPWord namespace'); - $this->assertTrue(PHPWord_Autoloader::load('PHPWord'), 'PHPWord_Autoloader::load() failed to autoload the PHPWord class'); + $this->assertNull( + PHPWord_Autoloader::load('Foo'), + 'PHPWord_Autoloader::load() is trying to load classes outside of the PHPWord namespace' + ); + $this->assertTrue( + PHPWord_Autoloader::load('PHPWord'), + 'PHPWord_Autoloader::load() failed to autoload the PHPWord class' + ); } public function testAutoload() @@ -25,8 +30,20 @@ public function testAutoload() $declared = get_declared_classes(); $declaredCount = count($declared); Autoloader::autoload('Foo'); - $this->assertEquals($declaredCount, count(get_declared_classes()), 'PHPWord\\Autoloader::autoload() is trying to load classes outside of the PHPWord namespace'); - Autoloader::autoload('PHPWord\\Exceptions\\InvalidStyleException'); // TODO change this class to the main PHPWord class when it is namespaced - $this->assertTrue(in_array('PHPWord\\Exceptions\\InvalidStyleException', get_declared_classes()), 'PHPWord\\Autoloader::autoload() failed to autoload the PHPWord\\Exceptions\\InvalidStyleException class'); + $this->assertEquals( + $declaredCount, + count(get_declared_classes()), + 'PhpOffice\\PhpWord\\Autoloader::autoload() is trying to load classes ' . + 'outside of the PhpOffice\\PhpWord namespace' + ); + // TODO change this class to the main PHPWord class when it is namespaced + Autoloader::autoload( + 'PhpOffice\\PhpWord\\Exceptions\\InvalidStyleException' + ); + $this->assertTrue( + in_array('PhpOffice\\PhpWord\\Exceptions\\InvalidStyleException', get_declared_classes()), + 'PhpOffice\\PhpWord\\Autoloader::autoload() failed to autoload the ' . + 'PhpOffice\\PhpWord\\Exceptions\\InvalidStyleException class' + ); } -} \ No newline at end of file +} diff --git a/Tests/PHPWord/DocumentPropertiesTest.php b/Tests/PHPWord/DocumentPropertiesTest.php new file mode 100644 index 0000000000..f98a9907b2 --- /dev/null +++ b/Tests/PHPWord/DocumentPropertiesTest.php @@ -0,0 +1,221 @@ +setCreator(); + $this->assertEquals('', $oProperties->getCreator()); + + $oProperties->setCreator('AAA'); + $this->assertEquals('AAA', $oProperties->getCreator()); + } + + public function testLastModifiedBy() + { + $oProperties = new PHPWord_DocumentProperties(); + $oProperties->setLastModifiedBy(); + $this->assertEquals('', $oProperties->getLastModifiedBy()); + + $oProperties->setLastModifiedBy('AAA'); + $this->assertEquals('AAA', $oProperties->getLastModifiedBy()); + } + + public function testCreated() + { + $oProperties = new PHPWord_DocumentProperties(); + $oProperties->setCreated(); + $this->assertEquals(time(), $oProperties->getCreated()); + + $iTime = time() + 3600; + $oProperties->setCreated($iTime); + $this->assertEquals($iTime, $oProperties->getCreated()); + } + + public function testModified() + { + $oProperties = new PHPWord_DocumentProperties(); + $oProperties->setModified(); + $this->assertEquals(time(), $oProperties->getModified()); + + $iTime = time() + 3600; + $oProperties->setModified($iTime); + $this->assertEquals($iTime, $oProperties->getModified()); + } + + public function testTitle() + { + $oProperties = new PHPWord_DocumentProperties(); + $oProperties->setTitle(); + $this->assertEquals('', $oProperties->getTitle()); + + $oProperties->setTitle('AAA'); + $this->assertEquals('AAA', $oProperties->getTitle()); + } + + public function testDescription() + { + $oProperties = new PHPWord_DocumentProperties(); + $oProperties->setDescription(); + $this->assertEquals('', $oProperties->getDescription()); + + $oProperties->setDescription('AAA'); + $this->assertEquals('AAA', $oProperties->getDescription()); + } + + public function testSubject() + { + $oProperties = new PHPWord_DocumentProperties(); + $oProperties->setSubject(); + $this->assertEquals('', $oProperties->getSubject()); + + $oProperties->setSubject('AAA'); + $this->assertEquals('AAA', $oProperties->getSubject()); + } + + public function testKeywords() + { + $oProperties = new PHPWord_DocumentProperties(); + $oProperties->setKeywords(); + $this->assertEquals('', $oProperties->getKeywords()); + + $oProperties->setKeywords('AAA'); + $this->assertEquals('AAA', $oProperties->getKeywords()); + } + + public function testCategory() + { + $oProperties = new PHPWord_DocumentProperties(); + $oProperties->setCategory(); + $this->assertEquals('', $oProperties->getCategory()); + + $oProperties->setCategory('AAA'); + $this->assertEquals('AAA', $oProperties->getCategory()); + } + + public function testCompany() + { + $oProperties = new PHPWord_DocumentProperties(); + $oProperties->setCompany(); + $this->assertEquals('', $oProperties->getCompany()); + + $oProperties->setCompany('AAA'); + $this->assertEquals('AAA', $oProperties->getCompany()); + } + + public function testManager() + { + $oProperties = new PHPWord_DocumentProperties(); + $oProperties->setManager(); + $this->assertEquals('', $oProperties->getManager()); + + $oProperties->setManager('AAA'); + $this->assertEquals('AAA', $oProperties->getManager()); + } + + public function testCustomProperty() + { + $oProperties = new PHPWord_DocumentProperties(); + $oProperties->setCustomProperty('key1', null); + $oProperties->setCustomProperty('key2', true); + $oProperties->setCustomProperty('key3', 3); + $oProperties->setCustomProperty('key4', 4.4); + $oProperties->setCustomProperty('key5', 'value5'); + $this->assertEquals( + PHPWord_DocumentProperties::PROPERTY_TYPE_STRING, + $oProperties->getCustomPropertyType('key1') + ); + $this->assertEquals( + PHPWord_DocumentProperties::PROPERTY_TYPE_BOOLEAN, + $oProperties->getCustomPropertyType('key2') + ); + $this->assertEquals( + PHPWord_DocumentProperties::PROPERTY_TYPE_INTEGER, + $oProperties->getCustomPropertyType('key3') + ); + $this->assertEquals( + PHPWord_DocumentProperties::PROPERTY_TYPE_FLOAT, + $oProperties->getCustomPropertyType('key4') + ); + $this->assertEquals( + PHPWord_DocumentProperties::PROPERTY_TYPE_STRING, + $oProperties->getCustomPropertyType('key5') + ); + $this->assertEquals(null, $oProperties->getCustomPropertyType('key6')); + $this->assertEquals(null, $oProperties->getCustomPropertyValue('key1')); + $this->assertEquals(true, $oProperties->getCustomPropertyValue('key2')); + $this->assertEquals(3, $oProperties->getCustomPropertyValue('key3')); + $this->assertEquals(4.4, $oProperties->getCustomPropertyValue('key4')); + $this->assertEquals('value5', $oProperties->getCustomPropertyValue('key5')); + $this->assertEquals(null, $oProperties->getCustomPropertyValue('key6')); + $this->assertEquals(true, $oProperties->isCustomPropertySet('key5')); + $this->assertEquals(false, $oProperties->isCustomPropertySet('key6')); + $this->assertEquals(array( + 'key1', + 'key2', + 'key3', + 'key4', + 'key5' + ), $oProperties->getCustomProperties()); + } + + public function testConvertProperty() + { + $this->assertEquals('', PHPWord_DocumentProperties::convertProperty('a', 'empty')); + $this->assertEquals(null, PHPWord_DocumentProperties::convertProperty('a', 'null')); + $this->assertEquals(8, PHPWord_DocumentProperties::convertProperty('8', 'int')); + $this->assertEquals(8, PHPWord_DocumentProperties::convertProperty('8.3', 'uint')); + $this->assertEquals(8.3, PHPWord_DocumentProperties::convertProperty('8.3', 'decimal')); + $this->assertEquals('8.3', PHPWord_DocumentProperties::convertProperty('8.3', 'lpstr')); + $this->assertEquals(strtotime('10/11/2013'), PHPWord_DocumentProperties::convertProperty('10/11/2013', 'date')); + $this->assertEquals(true, PHPWord_DocumentProperties::convertProperty('true', 'bool')); + $this->assertEquals(false, PHPWord_DocumentProperties::convertProperty('1', 'bool')); + $this->assertEquals('1', PHPWord_DocumentProperties::convertProperty('1', 'array')); + $this->assertEquals('1', PHPWord_DocumentProperties::convertProperty('1', '')); + + + $this->assertEquals( + PHPWord_DocumentProperties::PROPERTY_TYPE_INTEGER, + PHPWord_DocumentProperties::convertPropertyType('int') + ); + $this->assertEquals( + PHPWord_DocumentProperties::PROPERTY_TYPE_INTEGER, + PHPWord_DocumentProperties::convertPropertyType('uint') + ); + $this->assertEquals( + PHPWord_DocumentProperties::PROPERTY_TYPE_FLOAT, + PHPWord_DocumentProperties::convertPropertyType('decimal') + ); + $this->assertEquals( + PHPWord_DocumentProperties::PROPERTY_TYPE_STRING, + PHPWord_DocumentProperties::convertPropertyType('lpstr') + ); + $this->assertEquals( + PHPWord_DocumentProperties::PROPERTY_TYPE_DATE, + PHPWord_DocumentProperties::convertPropertyType('date') + ); + $this->assertEquals( + PHPWord_DocumentProperties::PROPERTY_TYPE_BOOLEAN, + PHPWord_DocumentProperties::convertPropertyType('bool') + ); + $this->assertEquals( + PHPWord_DocumentProperties::PROPERTY_TYPE_UNKNOWN, + PHPWord_DocumentProperties::convertPropertyType('array') + ); + $this->assertEquals( + PHPWord_DocumentProperties::PROPERTY_TYPE_UNKNOWN, + PHPWord_DocumentProperties::convertPropertyType('') + ); + } +} diff --git a/Tests/PHPWord/IOFactoryTest.php b/Tests/PHPWord/IOFactoryTest.php index f6f0aba8ce..7b15fbb876 100644 --- a/Tests/PHPWord/IOFactoryTest.php +++ b/Tests/PHPWord/IOFactoryTest.php @@ -1,59 +1,72 @@ assertAttributeEquals(PHPWord_IOFactory::getSearchLocations(), '_searchLocations','PHPWord_IOFactory'); - } - - public function testSetSearchLocationsWithArray() - { - PHPWord_IOFactory::setSearchLocations(array()); - $this->assertAttributeEquals(array(), '_searchLocations','PHPWord_IOFactory'); - } - - /** - * @expectedException Exception - * @expectedExceptionMessage Invalid parameter passed. - */ - public function testSetSearchLocationsWithNotArray() - { - PHPWord_IOFactory::setSearchLocations('String'); - } - - public function testAddSearchLocation() - { - PHPWord_IOFactory::setSearchLocations(array()); - PHPWord_IOFactory::addSearchLocation('type', 'location', 'classname'); - $this->assertAttributeEquals(array(array('type' => 'type', 'path' => 'location', 'class' => 'classname')), '_searchLocations','PHPWord_IOFactory'); - } - - /** - * @expectedException Exception - * @expectedExceptionMessage No IWriter found for type - */ - public function testCreateWriterException(){ - $oPHPWord = new PHPWord(); - - PHPWord_IOFactory::setSearchLocations(array()); - PHPWord_IOFactory::createWriter($oPHPWord); - } - - public function testCreateWriter(){ - $oPHPWord = new PHPWord(); - - $this->assertEquals(PHPWord_IOFactory::createWriter($oPHPWord, 'Word2007'), new PHPWord_Writer_Word2007($oPHPWord)); - } +class IOFactoryTest extends \PHPUnit_Framework_TestCase +{ + public function testGetSearchLocations() + { + $this->assertAttributeEquals( + PHPWord_IOFactory::getSearchLocations(), + '_searchLocations', + 'PHPWord_IOFactory' + ); + } + + public function testSetSearchLocationsWithArray() + { + PHPWord_IOFactory::setSearchLocations(array()); + $this->assertAttributeEquals(array(), '_searchLocations', 'PHPWord_IOFactory'); + } + + /** + * @expectedException Exception + * @expectedExceptionMessage Invalid parameter passed. + */ + public function testSetSearchLocationsWithNotArray() + { + PHPWord_IOFactory::setSearchLocations('String'); + } + + public function testAddSearchLocation() + { + PHPWord_IOFactory::setSearchLocations(array()); + PHPWord_IOFactory::addSearchLocation('type', 'location', 'classname'); + $this->assertAttributeEquals( + array(array('type' => 'type', 'path' => 'location', 'class' => 'classname')), + '_searchLocations', + 'PHPWord_IOFactory' + ); + } + + /** + * @expectedException Exception + * @expectedExceptionMessage No IWriter found for type + */ + public function testCreateWriterException() + { + $oPHPWord = new PHPWord(); + + PHPWord_IOFactory::setSearchLocations(array()); + PHPWord_IOFactory::createWriter($oPHPWord); + } + + public function testCreateWriter() + { + $oPHPWord = new PHPWord(); + + $this->assertEquals( + PHPWord_IOFactory::createWriter($oPHPWord, 'Word2007'), + new PHPWord_Writer_Word2007($oPHPWord) + ); + } } - \ No newline at end of file diff --git a/Tests/PHPWord/MediaTest.php b/Tests/PHPWord/MediaTest.php index 40460deace..b2ebd6ae89 100644 --- a/Tests/PHPWord/MediaTest.php +++ b/Tests/PHPWord/MediaTest.php @@ -1,29 +1,50 @@ assertEquals(PHPWord_Media::getSectionMediaElements(), array()); + } - public function testGetSectionMediaElementsWithNull() - { - $this->assertEquals(PHPWord_Media::getSectionMediaElements(), array()); - } + public function testCountSectionMediaElementsWithNull() + { + $this->assertEquals(PHPWord_Media::countSectionMediaElements(), 0); + } - public function testCountSectionMediaElementsWithNull() - { - $this->assertEquals(PHPWord_Media::countSectionMediaElements(), 0); - } + public function testGetHeaderMediaElements() + { + $this->assertAttributeEquals(PHPWord_Media::getHeaderMediaElements(), '_headerMedia', 'PHPWord_Media'); + } - public function testGetHeaderMediaElements() - { - $this->assertAttributeEquals(PHPWord_Media::getHeaderMediaElements(), '_headerMedia','PHPWord_Media'); - } + public function testGetFooterMediaElements() + { + $this->assertAttributeEquals(PHPWord_Media::getFooterMediaElements(), '_footerMedia', 'PHPWord_Media'); + } - public function testGetFooterMediaElements() - { - $this->assertAttributeEquals(PHPWord_Media::getFooterMediaElements(), '_footerMedia','PHPWord_Media'); - } + /** + * Todo: add memory image to this test + * + * @covers PHPWord_Media::addSectionMediaElement + */ + public function testAddSectionMediaElement() + { + $section = new PHPWord_Section(0); + $section->addImage(PHPWORD_TESTS_DIR_ROOT . "/_files/images/mars_noext_jpg"); + $section->addImage(PHPWORD_TESTS_DIR_ROOT . "/_files/images/mars.jpg"); + $section->addImage(PHPWORD_TESTS_DIR_ROOT . "/_files/images/mario.gif"); + $section->addImage(PHPWORD_TESTS_DIR_ROOT . "/_files/images/firefox.png"); + $section->addImage(PHPWORD_TESTS_DIR_ROOT . "/_files/images/duke_nukem.bmp"); + $section->addImage(PHPWORD_TESTS_DIR_ROOT . "/_files/images/angela_merkel.tif"); + + $elements = $section->getElements(); + $this->assertEquals(6, count($elements)); + foreach ($elements as $element) { + $this->assertInstanceOf('PHPWord_Section_Image', $element); + } + } } - \ No newline at end of file diff --git a/Tests/PHPWord/Reader/Word2007Test.php b/Tests/PHPWord/Reader/Word2007Test.php new file mode 100644 index 0000000000..6fb6684609 --- /dev/null +++ b/Tests/PHPWord/Reader/Word2007Test.php @@ -0,0 +1,68 @@ +assertTrue($object->canRead($file)); + } + + /** + * Test canRead() failure + * + * @expectedException Exception + */ + public function testCanReadFailed() + { + $dir = join( + DIRECTORY_SEPARATOR, + array(PHPWORD_TESTS_DIR_ROOT, '_files', 'documents') + ); + $object = new PHPWord_Reader_Word2007; + $file = $dir . DIRECTORY_SEPARATOR . 'foo.docx'; + $this->assertFalse($object->canRead($file)); + $object = PHPWord_IOFactory::load($file); + } + + /** + * Test load document + */ + public function testLoad() + { + $dir = join( + DIRECTORY_SEPARATOR, + array(PHPWORD_TESTS_DIR_ROOT, '_files', 'documents') + ); + $file = $dir . DIRECTORY_SEPARATOR . 'reader.docx'; + $object = PHPWord_IOFactory::load($file); + $this->assertInstanceOf('PHPWord', $object); + } +} diff --git a/Tests/PHPWord/Section/Footer/PreserveTextTest.php b/Tests/PHPWord/Section/Footer/PreserveTextTest.php new file mode 100644 index 0000000000..61f84ee56a --- /dev/null +++ b/Tests/PHPWord/Section/Footer/PreserveTextTest.php @@ -0,0 +1,36 @@ +assertInstanceOf('PHPWord_Section_Footer_PreserveText', $oPreserveText); + $this->assertEquals($oPreserveText->getText(), null); + $this->assertEquals($oPreserveText->getFontStyle(), null); + $this->assertEquals($oPreserveText->getParagraphStyle(), null); + } + + public function testConstructWithString() + { + $oPreserveText = new PHPWord_Section_Footer_PreserveText('text', 'styleFont', 'styleParagraph'); + $this->assertEquals($oPreserveText->getText(), 'text'); + $this->assertEquals($oPreserveText->getFontStyle(), 'styleFont'); + $this->assertEquals($oPreserveText->getParagraphStyle(), 'styleParagraph'); + } + + public function testConstructWithArray() + { + $oPreserveText = new PHPWord_Section_Footer_PreserveText( + 'text', + array('align' => 'center'), + array('marginLeft' => 600, 'marginRight' => 600, 'marginTop' => 600, 'marginBottom' => 600) + ); + $this->assertInstanceOf('PHPWord_Style_Font', $oPreserveText->getFontStyle()); + $this->assertInstanceOf('PHPWord_Style_Paragraph', $oPreserveText->getParagraphStyle()); + } +} diff --git a/Tests/PHPWord/Section/FooterTest.php b/Tests/PHPWord/Section/FooterTest.php new file mode 100644 index 0000000000..10751d0e7e --- /dev/null +++ b/Tests/PHPWord/Section/FooterTest.php @@ -0,0 +1,122 @@ +assertInstanceOf('PHPWord_Section_Footer', $oFooter); + $this->assertEquals($oFooter->getFooterCount(), $iVal); + } + + public function testRelationID() + { + $oFooter = new PHPWord_Section_Footer(0); + + $iVal = rand(1, 1000); + $oFooter->setRelationId($iVal); + $this->assertEquals($oFooter->getRelationId(), $iVal); + } + + public function testAddText() + { + $oFooter = new PHPWord_Section_Footer(1); + $element = $oFooter->addText('text'); + + $this->assertCount(1, $oFooter->getElements()); + $this->assertInstanceOf('PHPWord_Section_Text', $element); + + } + + public function testAddTextNotUTF8() + { + $oFooter = new PHPWord_Section_Footer(1); + $element = $oFooter->addText(utf8_decode('ééé')); + + $this->assertCount(1, $oFooter->getElements()); + $this->assertInstanceOf('PHPWord_Section_Text', $element); + $this->assertEquals($element->getText(), 'ééé'); + } + + public function testAddTextBreak() + { + $oFooter = new PHPWord_Section_Footer(1); + $iVal = rand(1, 1000); + $oFooter->addTextBreak($iVal); + + $this->assertCount($iVal, $oFooter->getElements()); + } + + public function testCreateTextRun() + { + $oFooter = new PHPWord_Section_Footer(1); + $element = $oFooter->createTextRun(); + + $this->assertCount(1, $oFooter->getElements()); + $this->assertInstanceOf('PHPWord_Section_TextRun', $element); + } + + public function testAddTable() + { + $oFooter = new PHPWord_Section_Footer(1); + $element = $oFooter->addTable(); + + $this->assertCount(1, $oFooter->getElements()); + $this->assertInstanceOf('PHPWord_Section_Table', $element); + } + + public function testAddImage() + { + $src = \join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'images', 'earth.jpg') + ); + $oFooter = new PHPWord_Section_Footer(1); + $element = $oFooter->addImage($src); + + $this->assertCount(1, $oFooter->getElements()); + $this->assertInstanceOf('PHPWord_Section_Image', $element); + } + + public function testAddMemoryImage() + { + $oFooter = new PHPWord_Section_Footer(1); + $element = $oFooter->addMemoryImage( + 'https://assets.mozillalabs.com/Brands-Logos/Thunderbird/logo-only/thunderbird_logo-only_RGB.png' + ); + + $this->assertCount(1, $oFooter->getElements()); + $this->assertInstanceOf('PHPWord_Section_MemoryImage', $element); + } + + public function testAddPreserveText() + { + $oFooter = new PHPWord_Section_Footer(1); + $element = $oFooter->addPreserveText('text'); + + $this->assertCount(1, $oFooter->getElements()); + $this->assertInstanceOf('PHPWord_Section_Footer_PreserveText', $element); + } + + public function testAddPreserveTextNotUTF8() + { + $oFooter = new PHPWord_Section_Footer(1); + $element = $oFooter->addPreserveText(utf8_decode('ééé')); + + $this->assertCount(1, $oFooter->getElements()); + $this->assertInstanceOf('PHPWord_Section_Footer_PreserveText', $element); + $this->assertEquals($element->getText(), 'ééé'); + } + + public function testGetElements() + { + $oFooter = new PHPWord_Section_Footer(1); + + $this->assertInternalType('array', $oFooter->getElements()); + } +} diff --git a/Tests/PHPWord/Section/FootnoteTest.php b/Tests/PHPWord/Section/FootnoteTest.php new file mode 100644 index 0000000000..bd991278ba --- /dev/null +++ b/Tests/PHPWord/Section/FootnoteTest.php @@ -0,0 +1,63 @@ +assertInstanceOf('PHPWord_Section_Footnote', $oFootnote); + $this->assertCount(0, $oFootnote->getElements()); + $this->assertEquals($oFootnote->getParagraphStyle(), null); + } + + public function testConstructString() + { + $oFootnote = new PHPWord_Section_Footnote('pStyle'); + + $this->assertEquals($oFootnote->getParagraphStyle(), 'pStyle'); + } + + public function testConstructArray() + { + $oFootnote = new PHPWord_Section_Footnote(array('spacing' => 100)); + + $this->assertInstanceOf('PHPWord_Style_Paragraph', $oFootnote->getParagraphStyle()); + } + + public function testAddText() + { + $oFootnote = new PHPWord_Section_Footnote(); + $element = $oFootnote->addText('text'); + + $this->assertCount(1, $oFootnote->getElements()); + $this->assertInstanceOf('PHPWord_Section_Text', $element); + } + + public function testAddLink() + { + $oFootnote = new PHPWord_Section_Footnote(); + $element = $oFootnote->addLink('http://www.google.fr'); + + $this->assertCount(1, $oFootnote->getElements()); + $this->assertInstanceOf('PHPWord_Section_Link', $element); + } + + public function testReferenceId() + { + $oFootnote = new PHPWord_Section_Footnote(); + + $iVal = rand(1, 1000); + $oFootnote->setReferenceId($iVal); + $this->assertEquals($oFootnote->getReferenceId(), $iVal); + } + + public function testGetElements() + { + $oFootnote = new PHPWord_Section_Footnote(); + $this->assertInternalType('array', $oFootnote->getElements()); + } +} diff --git a/Tests/PHPWord/Section/HeaderTest.php b/Tests/PHPWord/Section/HeaderTest.php new file mode 100644 index 0000000000..527ad3ee4c --- /dev/null +++ b/Tests/PHPWord/Section/HeaderTest.php @@ -0,0 +1,165 @@ +assertInstanceOf('PHPWord_Section_Header', $oHeader); + $this->assertEquals($oHeader->getHeaderCount(), $iVal); + $this->assertEquals($oHeader->getType(), PHPWord_Section_Header::AUTO); + } + + public function testAddText() + { + $oHeader = new PHPWord_Section_Header(1); + $element = $oHeader->addText('text'); + + $this->assertInstanceOf('PHPWord_Section_Text', $element); + $this->assertCount(1, $oHeader->getElements()); + $this->assertEquals($element->getText(), 'text'); + } + + public function testAddTextNotUTF8() + { + $oHeader = new PHPWord_Section_Header(1); + $element = $oHeader->addText(utf8_decode('ééé')); + + $this->assertInstanceOf('PHPWord_Section_Text', $element); + $this->assertCount(1, $oHeader->getElements()); + $this->assertEquals($element->getText(), 'ééé'); + } + + public function testAddTextBreak() + { + $oHeader = new PHPWord_Section_Header(1); + $oHeader->addTextBreak(); + $this->assertCount(1, $oHeader->getElements()); + } + + public function testAddTextBreakWithParams() + { + $oHeader = new PHPWord_Section_Header(1); + $iVal = rand(1, 1000); + $oHeader->addTextBreak($iVal); + $this->assertCount($iVal, $oHeader->getElements()); + } + + public function testCreateTextRun() + { + $oHeader = new PHPWord_Section_Header(1); + $element = $oHeader->createTextRun(); + $this->assertInstanceOf('PHPWord_Section_TextRun', $element); + $this->assertCount(1, $oHeader->getElements()); + } + + public function testAddTable() + { + $oHeader = new PHPWord_Section_Header(1); + $element = $oHeader->addTable(); + $this->assertInstanceOf('PHPWord_Section_Table', $element); + $this->assertCount(1, $oHeader->getElements()); + } + + public function testAddImage() + { + $src = \join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'images', 'earth.jpg') + ); + $oHeader = new PHPWord_Section_Header(1); + $element = $oHeader->addImage($src); + + $this->assertCount(1, $oHeader->getElements()); + $this->assertInstanceOf('PHPWord_Section_Image', $element); + } + + public function testAddMemoryImage() + { + $oHeader = new PHPWord_Section_Header(1); + $element = $oHeader->addMemoryImage( + 'https://assets.mozillalabs.com/Brands-Logos/Thunderbird/logo-only/thunderbird_logo-only_RGB.png' + ); + + $this->assertCount(1, $oHeader->getElements()); + $this->assertInstanceOf('PHPWord_Section_MemoryImage', $element); + } + + public function testAddPreserveText() + { + $oHeader = new PHPWord_Section_Header(1); + $element = $oHeader->addPreserveText('text'); + + $this->assertCount(1, $oHeader->getElements()); + $this->assertInstanceOf('PHPWord_Section_Footer_PreserveText', $element); + } + + public function testAddPreserveTextNotUTF8() + { + $oHeader = new PHPWord_Section_Header(1); + $element = $oHeader->addPreserveText(utf8_decode('ééé')); + + $this->assertCount(1, $oHeader->getElements()); + $this->assertInstanceOf('PHPWord_Section_Footer_PreserveText', $element); + $this->assertEquals($element->getText(), 'ééé'); + } + + public function testAddWatermark() + { + $src = \join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'images', 'earth.jpg') + ); + $oHeader = new PHPWord_Section_Header(1); + $element = $oHeader->addWatermark($src); + + $this->assertCount(1, $oHeader->getElements()); + $this->assertInstanceOf('PHPWord_Section_Image', $element); + } + + public function testGetElements() + { + $oHeader = new PHPWord_Section_Header(1); + + $this->assertInternalType('array', $oHeader->getElements()); + } + + public function testRelationId() + { + $oHeader = new PHPWord_Section_Header(1); + + $iVal = rand(1, 1000); + $oHeader->setRelationId($iVal); + $this->assertEquals($oHeader->getRelationId(), $iVal); + } + + public function testResetType() + { + $oHeader = new PHPWord_Section_Header(1); + $oHeader->firstPage(); + $oHeader->resetType(); + + $this->assertEquals($oHeader->getType(), PHPWord_Section_Header::AUTO); + } + + public function testFirstPage() + { + $oHeader = new PHPWord_Section_Header(1); + $oHeader->firstPage(); + + $this->assertEquals($oHeader->getType(), PHPWord_Section_Header::FIRST); + } + + public function testEvenPage() + { + $oHeader = new PHPWord_Section_Header(1); + $oHeader->evenPage(); + + $this->assertEquals($oHeader->getType(), PHPWord_Section_Header::EVEN); + } +} diff --git a/Tests/PHPWord/Section/ImageTest.php b/Tests/PHPWord/Section/ImageTest.php new file mode 100644 index 0000000000..50cc4d2acc --- /dev/null +++ b/Tests/PHPWord/Section/ImageTest.php @@ -0,0 +1,102 @@ +assertInstanceOf('PHPWord_Section_Image', $oImage); + $this->assertEquals($oImage->getSource(), $src); + $this->assertEquals($oImage->getMediaId(), md5($src)); + $this->assertEquals($oImage->getIsWatermark(), false); + $this->assertInstanceOf('PHPWord_Style_Image', $oImage->getStyle()); + } + + public function testConstructWithStyle() + { + $src = \join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'images', 'firefox.png') + ); + $oImage = new PHPWord_Section_Image( + $src, + array('width' => 210, 'height' => 210, 'align' => 'center', + 'wrappingStyle' => \PHPWord_Style_Image::WRAPPING_STYLE_BEHIND) + ); + + $this->assertInstanceOf('PHPWord_Style_Image', $oImage->getStyle()); + } + + /** + * @covers PHPWord_Section_Image::__construct + */ + public function testValidImageTypes() + { + new PHPWord_Section_Image(PHPWORD_TESTS_DIR_ROOT . "/_files/images/mars_noext_jpg"); + new PHPWord_Section_Image(PHPWORD_TESTS_DIR_ROOT . "/_files/images/mars.jpg"); + new PHPWord_Section_Image(PHPWORD_TESTS_DIR_ROOT . "/_files/images/mario.gif"); + new PHPWord_Section_Image(PHPWORD_TESTS_DIR_ROOT . "/_files/images/firefox.png"); + new PHPWord_Section_Image(PHPWORD_TESTS_DIR_ROOT . "/_files/images/duke_nukem.bmp"); + new PHPWord_Section_Image(PHPWORD_TESTS_DIR_ROOT . "/_files/images/angela_merkel.tif"); + } + + /** + * @expectedException \PhpOffice\PhpWord\Exceptions\InvalidImageException + * @covers PHPWord_Section_Image::__construct + */ + public function testImageNotFound() + { + new PHPWord_Section_Image(PHPWORD_TESTS_DIR_ROOT . "/_files/images/thisisnotarealimage"); + } + + /** + * @expectedException \PhpOffice\PhpWord\Exceptions\UnsupportedImageTypeException + * @covers PHPWord_Section_Image::__construct + */ + public function testInvalidImageTypes() + { + new PHPWord_Section_Image(PHPWORD_TESTS_DIR_ROOT . "/_files/images/alexz-johnson.pcx"); + } + + public function testStyle() + { + $oImage = new PHPWord_Section_Image(\join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'images', 'earth.jpg') + ), array('width' => 210, 'height' => 210, 'align' => 'center')); + + $this->assertInstanceOf('PHPWord_Style_Image', $oImage->getStyle()); + } + + public function testRelationID() + { + $oImage = new PHPWord_Section_Image(\join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'images', 'earth.jpg') + )); + + $iVal = rand(1, 1000); + $oImage->setRelationId($iVal); + $this->assertEquals($oImage->getRelationId(), $iVal); + } + + public function testWatermark() + { + $oImage = new PHPWord_Section_Image(\join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'images', 'earth.jpg') + )); + + $oImage->setIsWatermark(true); + $this->assertEquals($oImage->getIsWatermark(), true); + } +} diff --git a/Tests/PHPWord/Section/LinkTest.php b/Tests/PHPWord/Section/LinkTest.php new file mode 100644 index 0000000000..413b23fe95 --- /dev/null +++ b/Tests/PHPWord/Section/LinkTest.php @@ -0,0 +1,52 @@ +assertInstanceOf('PHPWord_Section_Link', $oLink); + $this->assertEquals($oLink->getLinkSrc(), 'http://www.google.com'); + $this->assertEquals($oLink->getLinkName(), null); + $this->assertEquals($oLink->getFontStyle(), null); + $this->assertEquals($oLink->getParagraphStyle(), null); + } + + public function testConstructWithParamsArray() + { + $oLink = new PHPWord_Section_Link( + 'http://www.google.com', + 'Search Engine', + array('color' => '0000FF', 'underline' => PHPWord_Style_Font::UNDERLINE_SINGLE), + array('marginLeft' => 600, 'marginRight' => 600, 'marginTop' => 600, 'marginBottom' => 600) + ); + + $this->assertInstanceOf('PHPWord_Section_Link', $oLink); + $this->assertEquals($oLink->getLinkSrc(), 'http://www.google.com'); + $this->assertEquals($oLink->getLinkName(), 'Search Engine'); + $this->assertInstanceOf('PHPWord_Style_Font', $oLink->getFontStyle()); + $this->assertInstanceOf('PHPWord_Style_Paragraph', $oLink->getParagraphStyle()); + } + + public function testConstructWithParamsString() + { + $oLink = new PHPWord_Section_Link('http://www.google.com', null, 'fontStyle', 'paragraphStyle'); + + $this->assertEquals($oLink->getFontStyle(), 'fontStyle'); + $this->assertEquals($oLink->getParagraphStyle(), 'paragraphStyle'); + } + + public function testRelationId() + { + $oLink = new PHPWord_Section_Link('http://www.google.com'); + + $iVal = rand(1, 1000); + $oLink->setRelationId($iVal); + $this->assertEquals($oLink->getRelationId(), $iVal); + } +} diff --git a/Tests/PHPWord/Section/ListItemTest.php b/Tests/PHPWord/Section/ListItemTest.php new file mode 100644 index 0000000000..a2a4d43832 --- /dev/null +++ b/Tests/PHPWord/Section/ListItemTest.php @@ -0,0 +1,36 @@ +assertInstanceOf('PHPWord_Section_Text', $oListItem->getTextObject()); + } + + public function testStyle() + { + $oListItem = new PHPWord_Section_ListItem( + 'text', + 1, + null, + array('listType' => PHPWord_Style_ListItem::TYPE_NUMBER) + ); + + $this->assertInstanceOf('PHPWord_Style_ListItem', $oListItem->getStyle()); + $this->assertEquals($oListItem->getStyle()->getListType(), PHPWord_Style_ListItem::TYPE_NUMBER); + } + + public function testDepth() + { + $iVal = rand(1, 1000); + $oListItem = new PHPWord_Section_ListItem('text', $iVal); + + $this->assertEquals($oListItem->getDepth(), $iVal); + } +} diff --git a/Tests/PHPWord/Section/MemoryImageTest.php b/Tests/PHPWord/Section/MemoryImageTest.php new file mode 100644 index 0000000000..3bfb39e358 --- /dev/null +++ b/Tests/PHPWord/Section/MemoryImageTest.php @@ -0,0 +1,94 @@ +assertInstanceOf('PHPWord_Section_MemoryImage', $oMemoryImage); + $this->assertEquals($oMemoryImage->getSource(), $src); + $this->assertEquals($oMemoryImage->getMediaId(), md5($src)); + $this->assertEquals($oMemoryImage->getImageCreateFunction(), 'imagecreatefrompng'); + $this->assertEquals($oMemoryImage->getImageFunction(), 'imagepng'); + $this->assertEquals($oMemoryImage->getImageExtension(), 'png'); + $this->assertEquals($oMemoryImage->getImageType(), 'image/png'); + } + + public function testGIF() + { + $src = \join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'images', 'mario.gif') + ); + $oMemoryImage = new PHPWord_Section_MemoryImage($src); + + $this->assertInstanceOf('PHPWord_Section_MemoryImage', $oMemoryImage); + $this->assertEquals($oMemoryImage->getSource(), $src); + $this->assertEquals($oMemoryImage->getMediaId(), md5($src)); + $this->assertEquals($oMemoryImage->getImageCreateFunction(), 'imagecreatefromgif'); + $this->assertEquals($oMemoryImage->getImageFunction(), 'imagegif'); + $this->assertEquals($oMemoryImage->getImageExtension(), 'gif'); + $this->assertEquals($oMemoryImage->getImageType(), 'image/gif'); + } + + public function testJPG() + { + $src = \join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'images', 'earth.jpg') + ); + $oMemoryImage = new PHPWord_Section_MemoryImage($src); + + $this->assertInstanceOf('PHPWord_Section_MemoryImage', $oMemoryImage); + $this->assertEquals($oMemoryImage->getSource(), $src); + $this->assertEquals($oMemoryImage->getMediaId(), md5($src)); + $this->assertEquals($oMemoryImage->getImageCreateFunction(), 'imagecreatefromjpeg'); + $this->assertEquals($oMemoryImage->getImageFunction(), 'imagejpeg'); + $this->assertEquals($oMemoryImage->getImageExtension(), 'jpg'); + $this->assertEquals($oMemoryImage->getImageType(), 'image/jpeg'); + } + + public function testBMP() + { + $oMemoryImage = new PHPWord_Section_MemoryImage(\join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'images', 'duke_nukem.bmp') + )); + + $this->assertInstanceOf('PHPWord_Section_MemoryImage', $oMemoryImage); + $this->assertEquals($oMemoryImage->getImageCreateFunction(), null); + $this->assertEquals($oMemoryImage->getImageFunction(), null); + $this->assertEquals($oMemoryImage->getImageExtension(), null); + $this->assertEquals($oMemoryImage->getImageType(), 'image/x-ms-bmp'); + } + + public function testStyle() + { + $oMemoryImage = new PHPWord_Section_MemoryImage(\join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'images', 'earth.jpg') + ), array('width' => 210, 'height' => 210, 'align' => 'center')); + + $this->assertInstanceOf('PHPWord_Style_Image', $oMemoryImage->getStyle()); + } + + public function testRelationID() + { + $oMemoryImage = new PHPWord_Section_MemoryImage(\join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'images', 'earth.jpg') + )); + + $iVal = rand(1, 1000); + $oMemoryImage->setRelationId($iVal); + $this->assertEquals($oMemoryImage->getRelationId(), $iVal); + } +} diff --git a/Tests/PHPWord/Section/ObjectTest.php b/Tests/PHPWord/Section/ObjectTest.php new file mode 100644 index 0000000000..b72f2484c8 --- /dev/null +++ b/Tests/PHPWord/Section/ObjectTest.php @@ -0,0 +1,85 @@ +assertInstanceOf('PHPWord_Section_Object', $oObject); + $this->assertInstanceOf('PHPWord_Style_Image', $oObject->getStyle()); + $this->assertEquals($oObject->getSource(), $src); + } + + public function testConstructWithNotSupportedFiles() + { + $src = \join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'xsl', 'passthrough.xsl') + ); + $oObject = new PHPWord_Section_Object($src); + + $this->assertInstanceOf('PHPWord_Section_Object', $oObject); + $this->assertEquals($oObject->getSource(), null); + $this->assertEquals($oObject->getStyle(), null); + } + + public function testConstructWithSupportedFilesAndStyle() + { + $src = \join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'documents', 'sheet.xls') + ); + $oObject = new PHPWord_Section_Object($src, array('width' => '230px')); + + $this->assertInstanceOf('PHPWord_Section_Object', $oObject); + $this->assertInstanceOf('PHPWord_Style_Image', $oObject->getStyle()); + $this->assertEquals($oObject->getSource(), $src); + } + + public function testRelationId() + { + $src = \join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'documents', 'sheet.xls') + ); + $oObject = new PHPWord_Section_Object($src); + + $iVal = rand(1, 1000); + $oObject->setRelationId($iVal); + $this->assertEquals($oObject->getRelationId(), $iVal); + } + + public function testImageRelationId() + { + $src = \join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'documents', 'sheet.xls') + ); + $oObject = new PHPWord_Section_Object($src); + + $iVal = rand(1, 1000); + $oObject->setImageRelationId($iVal); + $this->assertEquals($oObject->getImageRelationId(), $iVal); + } + + public function testObjectId() + { + $src = \join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'documents', 'sheet.xls') + ); + $oObject = new PHPWord_Section_Object($src); + + $iVal = rand(1, 1000); + $oObject->setObjectId($iVal); + $this->assertEquals($oObject->getObjectId(), $iVal); + } +} diff --git a/Tests/PHPWord/Section/PageBreakTest.php b/Tests/PHPWord/Section/PageBreakTest.php new file mode 100644 index 0000000000..5efd0fe944 --- /dev/null +++ b/Tests/PHPWord/Section/PageBreakTest.php @@ -0,0 +1,18 @@ +assertInstanceOf('PHPWord_Section_PageBreak', $oPageBreak); + } +} diff --git a/Tests/PHPWord/Section/SettingsTest.php b/Tests/PHPWord/Section/SettingsTest.php new file mode 100644 index 0000000000..92e8465434 --- /dev/null +++ b/Tests/PHPWord/Section/SettingsTest.php @@ -0,0 +1,235 @@ +setSettingValue('_orientation', 'landscape'); + $this->assertEquals('landscape', $oSettings->getOrientation()); + $this->assertEquals(16838, $oSettings->getPageSizeW()); + $this->assertEquals(11906, $oSettings->getPageSizeH()); + + $oSettings->setSettingValue('_orientation', null); + $this->assertNull($oSettings->getOrientation()); + $this->assertEquals(11906, $oSettings->getPageSizeW()); + $this->assertEquals(16838, $oSettings->getPageSizeH()); + + $iVal = rand(1, 1000); + $oSettings->setSettingValue('_borderSize', $iVal); + $this->assertEquals(array($iVal, $iVal, $iVal, $iVal), $oSettings->getBorderSize()); + $this->assertEquals($iVal, $oSettings->getBorderBottomSize()); + $this->assertEquals($iVal, $oSettings->getBorderLeftSize()); + $this->assertEquals($iVal, $oSettings->getBorderRightSize()); + $this->assertEquals($iVal, $oSettings->getBorderTopSize()); + + $oSettings->setSettingValue('_borderColor', 'FF00AA'); + $this->assertEquals(array('FF00AA', 'FF00AA', 'FF00AA', 'FF00AA'), $oSettings->getBorderColor()); + $this->assertEquals('FF00AA', $oSettings->getBorderBottomColor()); + $this->assertEquals('FF00AA', $oSettings->getBorderLeftColor()); + $this->assertEquals('FF00AA', $oSettings->getBorderRightColor()); + $this->assertEquals('FF00AA', $oSettings->getBorderTopColor()); + + $iVal = rand(1, 1000); + $oSettings->setSettingValue('headerHeight', $iVal); + $this->assertEquals($iVal, $oSettings->getHeaderHeight()); + } + + public function testMargin() + { + // Section Settings + $oSettings = new PHPWord_Section_Settings(); + + $iVal = rand(1, 1000); + $oSettings->setMarginTop($iVal); + $this->assertEquals($iVal, $oSettings->getMarginTop()); + + $iVal = rand(1, 1000); + $oSettings->setMarginBottom($iVal); + $this->assertEquals($iVal, $oSettings->getMarginBottom()); + + $iVal = rand(1, 1000); + $oSettings->setMarginLeft($iVal); + $this->assertEquals($iVal, $oSettings->getMarginLeft()); + + $iVal = rand(1, 1000); + $oSettings->setMarginRight($iVal); + $this->assertEquals($iVal, $oSettings->getMarginRight()); + } + + public function testOrientationLandscape() + { + // Section Settings + $oSettings = new PHPWord_Section_Settings(); + + $oSettings->setLandscape(); + $this->assertEquals('landscape', $oSettings->getOrientation()); + $this->assertEquals(16838, $oSettings->getPageSizeW()); + $this->assertEquals(11906, $oSettings->getPageSizeH()); + } + + public function testOrientationPortrait() + { + // Section Settings + $oSettings = new PHPWord_Section_Settings(); + + $oSettings->setPortrait(); + $this->assertNull($oSettings->getOrientation()); + $this->assertEquals(11906, $oSettings->getPageSizeW()); + $this->assertEquals(16838, $oSettings->getPageSizeH()); + } + + public function testBorderSize() + { + // Section Settings + $oSettings = new PHPWord_Section_Settings(); + + $iVal = rand(1, 1000); + $oSettings->setBorderSize($iVal); + $this->assertEquals(array($iVal, $iVal, $iVal, $iVal), $oSettings->getBorderSize()); + $this->assertEquals($iVal, $oSettings->getBorderBottomSize()); + $this->assertEquals($iVal, $oSettings->getBorderLeftSize()); + $this->assertEquals($iVal, $oSettings->getBorderRightSize()); + $this->assertEquals($iVal, $oSettings->getBorderTopSize()); + + $iVal = rand(1, 1000); + $oSettings->setBorderBottomSize($iVal); + $this->assertEquals($iVal, $oSettings->getBorderBottomSize()); + + $iVal = rand(1, 1000); + $oSettings->setBorderLeftSize($iVal); + $this->assertEquals($iVal, $oSettings->getBorderLeftSize()); + + $iVal = rand(1, 1000); + $oSettings->setBorderRightSize($iVal); + $this->assertEquals($iVal, $oSettings->getBorderRightSize()); + + $iVal = rand(1, 1000); + $oSettings->setBorderTopSize($iVal); + $this->assertEquals($iVal, $oSettings->getBorderTopSize()); + } + + public function testBorderColor() + { + // Section Settings + $oSettings = new PHPWord_Section_Settings(); + + $oSettings->setBorderColor('FF00AA'); + $this->assertEquals(array('FF00AA', 'FF00AA', 'FF00AA', 'FF00AA'), $oSettings->getBorderColor()); + $this->assertEquals('FF00AA', $oSettings->getBorderBottomColor()); + $this->assertEquals('FF00AA', $oSettings->getBorderLeftColor()); + $this->assertEquals('FF00AA', $oSettings->getBorderRightColor()); + $this->assertEquals('FF00AA', $oSettings->getBorderTopColor()); + + $oSettings->setBorderBottomColor('BBCCDD'); + $this->assertEquals('BBCCDD', $oSettings->getBorderBottomColor()); + + $oSettings->setBorderLeftColor('CCDDEE'); + $this->assertEquals('CCDDEE', $oSettings->getBorderLeftColor()); + + $oSettings->setBorderRightColor('11EE22'); + $this->assertEquals('11EE22', $oSettings->getBorderRightColor()); + + $oSettings->setBorderTopColor('22FF33'); + $this->assertEquals('22FF33', $oSettings->getBorderTopColor()); + } + + public function testNumberingStart() + { + // Section Settings + $oSettings = new PHPWord_Section_Settings(); + + $this->assertNull($oSettings->getPageNumberingStart()); + + $iVal = rand(1, 1000); + $oSettings->setPageNumberingStart($iVal); + $this->assertEquals($iVal, $oSettings->getPageNumberingStart()); + + $oSettings->setPageNumberingStart(); + $this->assertNull($oSettings->getPageNumberingStart()); + } + + public function testHeader() + { + // Section Settings + $oSettings = new PHPWord_Section_Settings(); + + $this->assertEquals(720, $oSettings->getHeaderHeight()); + + $iVal = rand(1, 1000); + $oSettings->setHeaderHeight($iVal); + $this->assertEquals($iVal, $oSettings->getHeaderHeight()); + + $oSettings->setHeaderHeight(); + $this->assertEquals(720, $oSettings->getHeaderHeight()); + } + + public function testFooter() + { + // Section Settings + $oSettings = new PHPWord_Section_Settings(); + + $this->assertEquals(720, $oSettings->getFooterHeight()); + + $iVal = rand(1, 1000); + $oSettings->setFooterHeight($iVal); + $this->assertEquals($iVal, $oSettings->getFooterHeight()); + + $oSettings->setFooterHeight(); + $this->assertEquals(720, $oSettings->getFooterHeight()); + } + + public function testColumnsNum() + { + // Section Settings + $oSettings = new PHPWord_Section_Settings(); + + // Default + $this->assertEquals(1, $oSettings->getColsNum()); + + $iVal = rand(1, 1000); + $oSettings->setColsNum($iVal); + $this->assertEquals($iVal, $oSettings->getColsNum()); + + $oSettings->setColsNum(); + $this->assertEquals(1, $oSettings->getColsNum()); + } + + public function testColumnsSpace() + { + // Section Settings + $oSettings = new PHPWord_Section_Settings(); + + // Default + $this->assertEquals(720, $oSettings->getColsSpace()); + + $iVal = rand(1, 1000); + $this->assertInstanceOf('PHPWord_Section_Settings', $oSettings->setColsSpace($iVal)); + $this->assertEquals($iVal, $oSettings->getColsSpace()); + + $this->assertInstanceOf('PHPWord_Section_Settings', $oSettings->setColsSpace()); + $this->assertEquals(720, $oSettings->getColsSpace()); + } + + public function testBreakType() + { + // Section Settings + $oSettings = new PHPWord_Section_Settings(); + + $this->assertNull($oSettings->getBreakType()); + + $oSettings->setBreakType('continuous'); + $this->assertEquals('continuous', $oSettings->getBreakType()); + + $oSettings->setBreakType(); + $this->assertNull($oSettings->getBreakType()); + } +} diff --git a/Tests/PHPWord/Section/Table/CellTest.php b/Tests/PHPWord/Section/Table/CellTest.php new file mode 100644 index 0000000000..30a7fcdb7a --- /dev/null +++ b/Tests/PHPWord/Section/Table/CellTest.php @@ -0,0 +1,209 @@ +assertInstanceOf('PHPWord_Section_Table_Cell', $oCell); + $this->assertEquals($oCell->getWidth(), null); + } + + public function testConstructWithStyleArray() + { + $iVal = rand(1, 1000); + $oCell = new PHPWord_Section_Table_Cell('section', $iVal, null, array('valign' => 'center')); + + $this->assertInstanceOf('PHPWord_Style_Cell', $oCell->getStyle()); + $this->assertEquals($oCell->getWidth(), null); + } + + public function testConstructWithStyleString() + { + $iVal = rand(1, 1000); + $oCell = new PHPWord_Section_Table_Cell('section', $iVal, null, 'cellStyle'); + + $this->assertEquals($oCell->getStyle(), 'cellStyle'); + } + + public function testAddText() + { + $oCell = new PHPWord_Section_Table_Cell('section', 1); + $element = $oCell->addText('text'); + + $this->assertCount(1, $oCell->getElements()); + $this->assertInstanceOf('PHPWord_Section_Text', $element); + } + + public function testAddTextNotUTF8() + { + $oCell = new PHPWord_Section_Table_Cell('section', 1); + $element = $oCell->addText(utf8_decode('ééé')); + + $this->assertCount(1, $oCell->getElements()); + $this->assertInstanceOf('PHPWord_Section_Text', $element); + $this->assertEquals($element->getText(), 'ééé'); + } + + public function testAddLink() + { + $oCell = new PHPWord_Section_Table_Cell('section', 1); + $element = $oCell->addLink('http://www.google.fr', 'Nom'); + + $this->assertCount(1, $oCell->getElements()); + $this->assertInstanceOf('PHPWord_Section_Link', $element); + } + + public function testAddTextBreak() + { + $oCell = new PHPWord_Section_Table_Cell('section', 1); + $oCell->addTextBreak(); + + $this->assertCount(1, $oCell->getElements()); + } + + public function testAddListItem() + { + $oCell = new PHPWord_Section_Table_Cell('section', 1); + $element = $oCell->addListItem('text'); + + $this->assertCount(1, $oCell->getElements()); + $this->assertInstanceOf('PHPWord_Section_ListItem', $element); + $this->assertEquals($element->getTextObject()->getText(), 'text'); + } + + public function testAddListItemNotUTF8() + { + $oCell = new PHPWord_Section_Table_Cell('section', 1); + $element = $oCell->addListItem(utf8_decode('ééé')); + + $this->assertCount(1, $oCell->getElements()); + $this->assertInstanceOf('PHPWord_Section_ListItem', $element); + $this->assertEquals($element->getTextObject()->getText(), 'ééé'); + } + + public function testAddImageSection() + { + $src = \join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'images', 'earth.jpg') + ); + $oCell = new PHPWord_Section_Table_Cell('section', 1); + $element = $oCell->addImage($src); + + $this->assertCount(1, $oCell->getElements()); + $this->assertInstanceOf('PHPWord_Section_Image', $element); + } + + public function testAddImageHeader() + { + $src = \join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'images', 'earth.jpg') + ); + $oCell = new PHPWord_Section_Table_Cell('header', 1); + $element = $oCell->addImage($src); + + $this->assertCount(1, $oCell->getElements()); + $this->assertInstanceOf('PHPWord_Section_Image', $element); + } + + public function testAddImageFooter() + { + $src = \join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'images', 'earth.jpg') + ); + $oCell = new PHPWord_Section_Table_Cell('footer', 1); + $element = $oCell->addImage($src); + + $this->assertCount(1, $oCell->getElements()); + $this->assertInstanceOf('PHPWord_Section_Image', $element); + } + + public function testAddMemoryImageSection() + { + $oCell = new PHPWord_Section_Table_Cell('section', 1); + $element = $oCell->addMemoryImage( + 'https://assets.mozillalabs.com/Brands-Logos/Thunderbird/logo-only/thunderbird_logo-only_RGB.png' + ); + + $this->assertCount(1, $oCell->getElements()); + $this->assertInstanceOf('PHPWord_Section_MemoryImage', $element); + } + + public function testAddMemoryImageHeader() + { + $oCell = new PHPWord_Section_Table_Cell('header', 1); + $element = $oCell->addMemoryImage( + 'https://assets.mozillalabs.com/Brands-Logos/Thunderbird/logo-only/thunderbird_logo-only_RGB.png' + ); + + $this->assertCount(1, $oCell->getElements()); + $this->assertInstanceOf('PHPWord_Section_MemoryImage', $element); + } + + public function testAddMemoryImageFooter() + { + $oCell = new PHPWord_Section_Table_Cell('footer', 1); + $element = $oCell->addMemoryImage( + 'https://assets.mozillalabs.com/Brands-Logos/Thunderbird/logo-only/thunderbird_logo-only_RGB.png' + ); + + $this->assertCount(1, $oCell->getElements()); + $this->assertInstanceOf('PHPWord_Section_MemoryImage', $element); + } + + public function testAddObjectXLS() + { + $src = \join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'documents', 'sheet.xls') + ); + $oCell = new PHPWord_Section_Table_Cell('section', 1); + $element = $oCell->addObject($src); + + $this->assertCount(1, $oCell->getElements()); + $this->assertInstanceOf('PHPWord_Section_Object', $element); + } + + public function testAddPreserveText() + { + $oCell = new PHPWord_Section_Table_Cell('header', 1); + $element = $oCell->addPreserveText('text'); + + $this->assertCount(1, $oCell->getElements()); + $this->assertInstanceOf('PHPWord_Section_Footer_PreserveText', $element); + } + + public function testAddPreserveTextNotUTF8() + { + $oCell = new PHPWord_Section_Table_Cell('header', 1); + $element = $oCell->addPreserveText(utf8_decode('ééé')); + + $this->assertCount(1, $oCell->getElements()); + $this->assertInstanceOf('PHPWord_Section_Footer_PreserveText', $element); + $this->assertEquals($element->getText(), 'ééé'); + } + + public function testCreateTextRun() + { + $oCell = new PHPWord_Section_Table_Cell('section', 1); + $element = $oCell->createTextRun(); + + $this->assertCount(1, $oCell->getElements()); + $this->assertInstanceOf('PHPWord_Section_TextRun', $element); + } + + public function testGetElements() + { + $oCell = new PHPWord_Section_Table_Cell('section', 1); + + $this->assertInternalType('array', $oCell->getElements()); + } +} diff --git a/Tests/PHPWord/Section/Table/RowTest.php b/Tests/PHPWord/Section/Table/RowTest.php new file mode 100644 index 0000000000..e62a5bd926 --- /dev/null +++ b/Tests/PHPWord/Section/Table/RowTest.php @@ -0,0 +1,43 @@ +assertInstanceOf('PHPWord_Section_Table_Row', $oRow); + $this->assertEquals($oRow->getHeight(), null); + $this->assertInternalType('array', $oRow->getCells()); + $this->assertCount(0, $oRow->getCells()); + $this->assertInstanceOf('PHPWord_Style_Row', $oRow->getStyle()); + } + + public function testConstructWithParams() + { + $iVal = rand(1, 1000); + $iVal2 = rand(1, 1000); + $oRow = new PHPWord_Section_Table_Row( + 'section', + $iVal, + $iVal2, + array('borderBottomSize' => 18, 'borderBottomColor' => '0000FF', 'bgColor' => '66BBFF') + ); + + $this->assertEquals($oRow->getHeight(), $iVal2); + $this->assertInstanceOf('PHPWord_Style_Row', $oRow->getStyle()); + } + + public function testAddCell() + { + $oRow = new PHPWord_Section_Table_Row('section', 1); + $element = $oRow->addCell(); + + $this->assertInstanceOf('PHPWord_Section_Table_Cell', $element); + $this->assertCount(1, $oRow->getCells()); + } +} diff --git a/Tests/PHPWord/Section/TableTest.php b/Tests/PHPWord/Section/TableTest.php new file mode 100644 index 0000000000..167f1190f0 --- /dev/null +++ b/Tests/PHPWord/Section/TableTest.php @@ -0,0 +1,60 @@ +assertInstanceOf('PHPWord_Section_Table', $oTable); + $this->assertEquals($oTable->getStyle(), null); + $this->assertEquals($oTable->getWidth(), null); + $this->assertEquals($oTable->getRows(), array()); + $this->assertCount(0, $oTable->getRows()); + } + + public function testStyleText() + { + $oTable = new PHPWord_Section_Table('section', 1, 'tableStyle'); + + $this->assertEquals($oTable->getStyle(), 'tableStyle'); + } + + public function testStyleArray() + { + $oTable = new PHPWord_Section_Table( + 'section', + 1, + array('borderSize' => 6, 'borderColor' => '006699', 'cellMargin' => 80) + ); + + $this->assertInstanceOf('PHPWord_Style_Table', $oTable->getStyle()); + } + + public function testWidth() + { + $oTable = new PHPWord_Section_Table('section', 1); + $iVal = rand(1, 1000); + $oTable->setWidth($iVal); + $this->assertEquals($oTable->getWidth(), $iVal); + } + + public function testRow() + { + $oTable = new PHPWord_Section_Table('section', 1); + $element = $oTable->addRow(); + $this->assertInstanceOf('PHPWord_Section_Table_Row', $element); + $this->assertCount(1, $oTable->getRows()); + } + + public function testCell() + { + $oTable = new PHPWord_Section_Table('section', 1); + $oTable->addRow(); + $element = $oTable->addCell(); + $this->assertInstanceOf('PHPWord_Section_Table_Cell', $element); + } +} diff --git a/Tests/PHPWord/Section/TextBreakTest.php b/Tests/PHPWord/Section/TextBreakTest.php new file mode 100644 index 0000000000..761c04a395 --- /dev/null +++ b/Tests/PHPWord/Section/TextBreakTest.php @@ -0,0 +1,60 @@ +assertNull($object->getFontStyle()); + $this->assertNull($object->getParagraphStyle()); + } + + /** + * Construct with style object + */ + public function testConstructWithStyleObject() + { + $fStyle = new PHPWord_Style_Font(); + $pStyle = new PHPWord_Style_Paragraph(); + $object = new PHPWord_Section_TextBreak($fStyle, $pStyle); + $this->assertEquals($fStyle, $object->getFontStyle()); + $this->assertEquals($pStyle, $object->getParagraphStyle()); + } + + /** + * Construct with style array + */ + public function testConstructWithStyleArray() + { + $fStyle = array('size' => 12); + $pStyle = array('spacing' => 240); + $object = new PHPWord_Section_TextBreak($fStyle, $pStyle); + $this->assertInstanceOf('PHPWord_Style_Font', $object->getFontStyle()); + $this->assertInstanceOf('PHPWord_Style_Paragraph', $object->getParagraphStyle()); + } + + /** + * Construct with style name + */ + public function testConstructWithStyleName() + { + $fStyle = 'fStyle'; + $pStyle = 'pStyle'; + $object = new PHPWord_Section_TextBreak($fStyle, $pStyle); + $this->assertEquals($fStyle, $object->getFontStyle()); + $this->assertEquals($pStyle, $object->getParagraphStyle()); + } +} diff --git a/Tests/PHPWord/Section/TextRunTest.php b/Tests/PHPWord/Section/TextRunTest.php new file mode 100644 index 0000000000..81402476d0 --- /dev/null +++ b/Tests/PHPWord/Section/TextRunTest.php @@ -0,0 +1,97 @@ +assertInstanceOf('PHPWord_Section_TextRun', $oTextRun); + $this->assertCount(0, $oTextRun->getElements()); + $this->assertEquals($oTextRun->getParagraphStyle(), null); + } + + public function testConstructString() + { + $oTextRun = new PHPWord_Section_TextRun('pStyle'); + + $this->assertInstanceOf('PHPWord_Section_TextRun', $oTextRun); + $this->assertCount(0, $oTextRun->getElements()); + $this->assertEquals($oTextRun->getParagraphStyle(), 'pStyle'); + } + + public function testConstructArray() + { + $oTextRun = new PHPWord_Section_TextRun(array('spacing' => 100)); + + $this->assertInstanceOf('PHPWord_Section_TextRun', $oTextRun); + $this->assertCount(0, $oTextRun->getElements()); + $this->assertInstanceOf('PHPWord_Style_Paragraph', $oTextRun->getParagraphStyle()); + } + + public function testAddText() + { + $oTextRun = new PHPWord_Section_TextRun(); + $element = $oTextRun->addText('text'); + + $this->assertInstanceOf('PHPWord_Section_Text', $element); + $this->assertCount(1, $oTextRun->getElements()); + $this->assertEquals($element->getText(), 'text'); + } + + public function testAddTextNotUTF8() + { + $oTextRun = new PHPWord_Section_TextRun(); + $element = $oTextRun->addText(utf8_decode('ééé')); + + $this->assertInstanceOf('PHPWord_Section_Text', $element); + $this->assertCount(1, $oTextRun->getElements()); + $this->assertEquals($element->getText(), 'ééé'); + } + + public function testAddLink() + { + $oTextRun = new PHPWord_Section_TextRun(); + $element = $oTextRun->addLink('http://www.google.fr'); + + $this->assertInstanceOf('PHPWord_Section_Link', $element); + $this->assertCount(1, $oTextRun->getElements()); + $this->assertEquals($element->getLinkSrc(), 'http://www.google.fr'); + } + + public function testAddLinkWithName() + { + $oTextRun = new PHPWord_Section_TextRun(); + $element = $oTextRun->addLink('http://www.google.fr', utf8_decode('ééé')); + + $this->assertInstanceOf('PHPWord_Section_Link', $element); + $this->assertCount(1, $oTextRun->getElements()); + $this->assertEquals($element->getLinkSrc(), 'http://www.google.fr'); + $this->assertEquals($element->getLinkName(), 'ééé'); + } + + public function testAddImage() + { + $src = \join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'images', 'earth.jpg') + ); + $oTextRun = new PHPWord_Section_TextRun(); + $element = $oTextRun->addImage($src); + + $this->assertInstanceOf('PHPWord_Section_Image', $element); + $this->assertCount(1, $oTextRun->getElements()); + } + + public function testCreateFootnote() + { + $oTextRun = new PHPWord_Section_TextRun(); + $element = $oTextRun->createFootnote(); + + $this->assertInstanceOf('PHPWord_Section_Footnote', $element); + $this->assertCount(1, $oTextRun->getElements()); + } +} diff --git a/Tests/PHPWord/Section/TextTest.php b/Tests/PHPWord/Section/TextTest.php new file mode 100644 index 0000000000..1a33a730d7 --- /dev/null +++ b/Tests/PHPWord/Section/TextTest.php @@ -0,0 +1,42 @@ +assertInstanceOf('PHPWord_Section_Text', $oText); + $this->assertEquals(null, $oText->getText()); + $this->assertInstanceOf('PHPWord_Style_Font', $oText->getFontStyle()); + $this->assertInstanceOf('PHPWord_Style_Paragraph', $oText->getParagraphStyle()); + } + + public function testText() + { + $oText = new PHPWord_Section_Text('text'); + + $this->assertEquals($oText->getText(), 'text'); + } + + public function testFont() + { + $oText = new PHPWord_Section_Text('text', 'fontStyle'); + $this->assertEquals($oText->getFontStyle(), 'fontStyle'); + + $oText->setFontStyle(array('bold' => true, 'italic' => true, 'size' => 16)); + $this->assertInstanceOf('PHPWord_Style_Font', $oText->getFontStyle()); + } + + public function testParagraph() + { + $oText = new PHPWord_Section_Text('text', 'fontStyle', 'paragraphStyle'); + $this->assertEquals($oText->getParagraphStyle(), 'paragraphStyle'); + + $oText->setParagraphStyle(array('align' => 'center', 'spaceAfter' => 100)); + $this->assertInstanceOf('PHPWord_Style_Paragraph', $oText->getParagraphStyle()); + } +} diff --git a/Tests/PHPWord/Section/TitleTest.php b/Tests/PHPWord/Section/TitleTest.php new file mode 100644 index 0000000000..97ce5de66c --- /dev/null +++ b/Tests/PHPWord/Section/TitleTest.php @@ -0,0 +1,47 @@ +assertInstanceOf('PHPWord_Section_Title', $oTitle); + $this->assertEquals($oTitle->getText(), 'text'); + } + + public function testStyleNull() + { + $oTitle = new PHPWord_Section_Title('text'); + + $this->assertEquals($oTitle->getStyle(), null); + } + + public function testStyleNotNull() + { + $oTitle = new PHPWord_Section_Title('text', 1, 'style'); + + $this->assertEquals($oTitle->getStyle(), 'style'); + } + + public function testAnchor() + { + $oTitle = new PHPWord_Section_Title('text'); + + $iVal = rand(1, 1000); + $oTitle->setAnchor($iVal); + $this->assertEquals($oTitle->getAnchor(), $iVal); + } + + public function testBookmarkID() + { + $oTitle = new PHPWord_Section_Title('text'); + + $iVal = rand(1, 1000); + $oTitle->setBookmarkId($iVal); + $this->assertEquals($oTitle->getBookmarkId(), $iVal); + } +} diff --git a/Tests/PHPWord/SectionTest.php b/Tests/PHPWord/SectionTest.php index 0e90961de1..ac540d06a8 100644 --- a/Tests/PHPWord/SectionTest.php +++ b/Tests/PHPWord/SectionTest.php @@ -1,38 +1,133 @@ assertAttributeEquals($oSection->getSettings(), '_settings', new PHPWord_Section(0)); - } - - public function testGetElementss() - { - $oSection = new PHPWord_Section(0); - $this->assertAttributeEquals($oSection->getElements(), '_elementCollection',new PHPWord_Section(0)); - } - - public function testGetFooter() - { - $oSection = new PHPWord_Section(0); - $this->assertAttributeEquals($oSection->getFooter(), '_footer',new PHPWord_Section(0)); - } - - public function testGetHeaders() - { - $oSection = new PHPWord_Section(0); - $this->assertAttributeEquals($oSection->getHeaders(), '_headers',new PHPWord_Section(0)); - } - - public function testGetElements() - { - $oSection = new PHPWord_Section(0); - $this->assertAttributeEquals($oSection->getElements(), '_elementCollection',new PHPWord_Section(0)); - } +/** + * Class TOCTest + * + * @package PHPWord\Tests + * @covers PHPWord_Section + * @runTestsInSeparateProcesses + */ +class SectionTest extends \PHPUnit_Framework_TestCase +{ + /** + * @covers PHPWord_Section::getSettings + */ + public function testGetSettings() + { + $oSection = new PHPWord_Section(0); + $this->assertAttributeEquals($oSection->getSettings(), '_settings', new PHPWord_Section(0)); + } + + /** + * @covers PHPWord_Section::getElements + */ + public function testGetElements() + { + $oSection = new PHPWord_Section(0); + $this->assertAttributeEquals($oSection->getElements(), '_elementCollection', new PHPWord_Section(0)); + } + + /** + * @covers PHPWord_Section::getFooter + */ + public function testGetFooter() + { + $oSection = new PHPWord_Section(0); + $this->assertAttributeEquals($oSection->getFooter(), '_footer', new PHPWord_Section(0)); + } + + /** + * @covers PHPWord_Section::getHeaders + */ + public function testGetHeaders() + { + $oSection = new PHPWord_Section(0); + $this->assertAttributeEquals($oSection->getHeaders(), '_headers', new PHPWord_Section(0)); + } + + /** + * @covers PHPWord_Section::setSettings + */ + public function testSetSettings() + { + $expected = 'landscape'; + $object = new PHPWord_Section(0); + $object->setSettings(array('orientation' => $expected)); + $this->assertEquals($expected, $object->getSettings()->getOrientation()); + } + + /** + * @covers PHPWord_Section::addText + * @covers PHPWord_Section::addLink + * @covers PHPWord_Section::addTextBreak + * @covers PHPWord_Section::addPageBreak + * @covers PHPWord_Section::addTable + * @covers PHPWord_Section::addListItem + * @covers PHPWord_Section::addObject + * @covers PHPWord_Section::addImage + * @covers PHPWord_Section::addMemoryImage + * @covers PHPWord_Section::addTOC + * @covers PHPWord_Section::addTitle + * @covers PHPWord_Section::createTextRun + * @covers PHPWord_Section::createFootnote + */ + public function testAddElements() + { + $objectSource = join( + DIRECTORY_SEPARATOR, + array(PHPWORD_TESTS_DIR_ROOT, '_files', 'documents', 'sheet.xls') + ); + $imageSource = join( + DIRECTORY_SEPARATOR, + array(PHPWORD_TESTS_DIR_ROOT, '_files', 'images', 'PHPWord.png') + ); + $imageUrl = 'http://php.net//images/logos/php-med-trans-light.gif'; + + $section = new PHPWord_Section(0); + $section->addText(utf8_decode('ä')); + $section->addLink(utf8_decode('http://äää.com'), utf8_decode('ä')); + $section->addTextBreak(); + $section->addPageBreak(); + $section->addTable(); + $section->addListItem(utf8_decode('ä')); + $section->addObject($objectSource); + $section->addImage($imageSource); + $section->addMemoryImage($imageUrl); + $section->addTOC(); + $section->addTitle(utf8_decode('ä'), 1); + $section->createTextRun(); + $section->createFootnote(); + + $elementCollection = $section->getElements(); + $elementType = 'Link'; + $objectType = "PHPWord_Section_{$elementType}"; + $this->assertInstanceOf($objectType, $elementCollection[1]); + // $elementTypes = array('Text', 'Link', 'TextBreak', 'PageBreak', + // 'Table', 'ListItem', 'Object', 'Image', 'MemoryImage', 'TOC', + // 'Title', 'TextRun'); + // $i = 0; + // foreach ($elementTypes as $elementType) { + // $objectType = "PHPWord_Section_{$elementType}"; + // $this->assertInstanceOf($objectType, $elementCollection[$i]); + // $i++; + // } + } + + /** + * @covers PHPWord_Section::createHeader + * @covers PHPWord_Section::createFooter + */ + public function testCreateHeaderFooter() + { + $object = new PHPWord_Section(0); + $elements = array('Header', 'Footer'); + foreach ($elements as $element) { + $objectType = "PHPWord_Section_{$element}"; + $method = "create{$element}"; + $this->assertInstanceOf($objectType, $object->$method()); + } + } } - \ No newline at end of file diff --git a/Tests/PHPWord/SettingsTest.php b/Tests/PHPWord/SettingsTest.php new file mode 100644 index 0000000000..e61a212915 --- /dev/null +++ b/Tests/PHPWord/SettingsTest.php @@ -0,0 +1,26 @@ +assertTrue(PHPWord_Settings::getCompatibility()); + $this->assertTrue(PHPWord_Settings::setCompatibility(false)); + $this->assertFalse(PHPWord_Settings::getCompatibility()); + $this->assertFalse(PHPWord_Settings::setCompatibility('Non boolean')); + } +} diff --git a/Tests/PHPWord/Shared/DrawingTest.php b/Tests/PHPWord/Shared/DrawingTest.php new file mode 100644 index 0000000000..550ee67c6b --- /dev/null +++ b/Tests/PHPWord/Shared/DrawingTest.php @@ -0,0 +1,66 @@ +assertEquals(round($value * 9525), $result); + + $result = PHPWord_Shared_Drawing::EMUToPixels($value); + $this->assertEquals(round($value / 9525), $result); + + $result = PHPWord_Shared_Drawing::pixelsToPoints($value); + $this->assertEquals($value * 0.67777777, $result); + + $result = PHPWord_Shared_Drawing::pointsToPixels($value); + $this->assertEquals($value * 1.333333333, $result); + + $result = PHPWord_Shared_Drawing::degreesToAngle($value); + $this->assertEquals((int)round($value * 60000), $result); + + $result = PHPWord_Shared_Drawing::angleToDegrees($value); + $this->assertEquals(round($value / 60000), $result); + + $result = PHPWord_Shared_Drawing::pixelsToCentimeters($value); + $this->assertEquals($value * 0.028, $result); + + $result = PHPWord_Shared_Drawing::centimetersToPixels($value); + $this->assertEquals($value / 0.028, $result); + } + } + + /** + * Test htmlToRGB() + */ + public function testHtmlToRGB() + { + // Prepare test values [ original, expected ] + $values[] = array('#FF99DD', array(255, 153, 221)); // With # + $values[] = array('FF99DD', array(255, 153, 221)); // 6 characters + $values[] = array('F9D', array(255, 153, 221)); // 3 characters + $values[] = array('0F9D', false); // 4 characters + // Conduct test + foreach ($values as $value) { + $result = PHPWord_Shared_Drawing::htmlToRGB($value[0]); + $this->assertEquals($value[1], $result); + } + } +} diff --git a/Tests/PHPWord/Shared/FileTest.php b/Tests/PHPWord/Shared/FileTest.php new file mode 100644 index 0000000000..a5ac348f67 --- /dev/null +++ b/Tests/PHPWord/Shared/FileTest.php @@ -0,0 +1,57 @@ +assertTrue(PHPWord_Shared_File::file_exists('blank.docx')); + } + /** + * Test file_exists() + */ + public function testNoFileExists() + { + $dir = join(DIRECTORY_SEPARATOR, array( + PHPWORD_TESTS_DIR_ROOT, + '_files', + 'templates' + )); + chdir($dir); + $this->assertFalse(PHPWord_Shared_File::file_exists('404.docx')); + } + + /** + * Test realpath() + */ + public function testRealpath() + { + $dir = join(DIRECTORY_SEPARATOR, array( + PHPWORD_TESTS_DIR_ROOT, + '_files', + 'templates' + )); + chdir($dir); + $file = 'blank.docx'; + $expected = $dir . DIRECTORY_SEPARATOR . $file; + $this->assertEquals($expected, PHPWord_Shared_File::realpath($file)); + } +} diff --git a/Tests/PHPWord/Shared/FontTest.php b/Tests/PHPWord/Shared/FontTest.php new file mode 100644 index 0000000000..5a40e465c8 --- /dev/null +++ b/Tests/PHPWord/Shared/FontTest.php @@ -0,0 +1,45 @@ +assertEquals($original * 16 / 12, $result); + + $result = PHPWord_Shared_Font::inchSizeToPixels($original); + $this->assertEquals($original * 96, $result); + + $result = PHPWord_Shared_Font::centimeterSizeToPixels($original); + $this->assertEquals($original * 37.795275591, $result); + + $result = PHPWord_Shared_Font::centimeterSizeToTwips($original); + $this->assertEquals($original * 565.217, $result); + + $result = PHPWord_Shared_Font::inchSizeToTwips($original); + $this->assertEquals($original * 565.217 * 2.54, $result); + + $result = PHPWord_Shared_Font::pixelSizeToTwips($original); + $this->assertEquals($original * 565.217 / 37.795275591, $result); + + $result = PHPWord_Shared_Font::pointSizeToTwips($original); + $this->assertEquals($original * 20, $result); + } +} diff --git a/Tests/PHPWord/Shared/StringTest.php b/Tests/PHPWord/Shared/StringTest.php new file mode 100644 index 0000000000..3698e2e0e1 --- /dev/null +++ b/Tests/PHPWord/Shared/StringTest.php @@ -0,0 +1,33 @@ +assertTrue(PHPWord_Shared_String::IsUTF8('')); + $this->assertTrue(PHPWord_Shared_String::IsUTF8('éééé')); + $this->assertFalse(PHPWord_Shared_String::IsUTF8(utf8_decode('éééé'))); + } + + public function testControlCharacterOOXML2PHP() + { + $this->assertEquals('', PHPWord_Shared_String::ControlCharacterOOXML2PHP('')); + $this->assertEquals(chr(0x08), PHPWord_Shared_String::ControlCharacterOOXML2PHP('_x0008_')); + } + + public function testControlCharacterPHP2OOXML() + { + $this->assertEquals('', PHPWord_Shared_String::ControlCharacterPHP2OOXML('')); + $this->assertEquals('_x0008_', PHPWord_Shared_String::ControlCharacterPHP2OOXML(chr(0x08))); + } +} diff --git a/Tests/PHPWord/Style/CellTest.php b/Tests/PHPWord/Style/CellTest.php new file mode 100644 index 0000000000..0d47095128 --- /dev/null +++ b/Tests/PHPWord/Style/CellTest.php @@ -0,0 +1,76 @@ + 'left', + 'textDirection' => PHPWord_Style_Cell::TEXT_DIR_BTLR, + 'bgColor' => 'FFFF00', + 'borderTopSize' => 120, + 'borderTopColor' => 'FFFF00', + 'borderLeftSize' => 120, + 'borderLeftColor' => 'FFFF00', + 'borderRightSize' => 120, + 'borderRightColor' => 'FFFF00', + 'borderBottomSize' => 120, + 'borderBottomColor' => 'FFFF00', + 'gridSpan' => 2, + 'vMerge' => 2, + ); + foreach ($attributes as $key => $value) { + $set = "set{$key}"; + $get = "get{$key}"; + $object->$set($value); + $this->assertEquals($value, $object->$get()); + } + } + + /** + * Test border color + */ + public function testBorderColor() + { + $object = new PHPWord_Style_Cell(); + + $default = '000000'; + $value = 'FF0000'; + + $this->assertEquals($default, $object->getDefaultBorderColor()); + + $object->setStyleValue('_defaultBorderColor', $value); + $this->assertEquals($value, $object->getDefaultBorderColor()); + + $object->setStyleValue('_borderColor', $value); + $expected = array($value, $value, $value, $value); + $this->assertEquals($expected, $object->getBorderColor()); + } + + /** + * Test border size + */ + public function testBorderSize() + { + $object = new PHPWord_Style_Cell(); + + $value = 120; + $expected = array($value, $value, $value, $value); + $object->setStyleValue('_borderSize', $value); + $this->assertEquals($expected, $object->getBorderSize()); + } +} diff --git a/Tests/PHPWord/Style/FontTest.php b/Tests/PHPWord/Style/FontTest.php new file mode 100644 index 0000000000..46cec029b2 --- /dev/null +++ b/Tests/PHPWord/Style/FontTest.php @@ -0,0 +1,116 @@ + 'both')); + + $this->assertEquals('text', $object->getStyleType()); + $this->assertInstanceOf('PHPWord_Style_Paragraph', $object->getParagraphStyle()); + } + + /** + * Test setting style values with null or empty value + */ + public function testSetStyleValueWithNullOrEmpty() + { + $object = new PHPWord_Style_Font(); + + $attributes = array( + 'name' => PHPWord::DEFAULT_FONT_NAME, + 'size' => PHPWord::DEFAULT_FONT_SIZE, + 'bold' => false, + 'italic' => false, + 'superScript' => false, + 'subScript' => false, + 'underline' => PHPWord_Style_Font::UNDERLINE_NONE, + 'strikethrough' => false, + 'color' => PHPWord::DEFAULT_FONT_COLOR, + 'fgColor' => null, + ); + foreach ($attributes as $key => $default) { + $get = "get{$key}"; + $object->setStyleValue("_$key", null); + $this->assertEquals($default, $object->$get()); + $object->setStyleValue("_$key", ''); + $this->assertEquals($default, $object->$get()); + } + } + + /** + * Test setting style values with normal value + */ + public function testSetStyleValueNormal() + { + $object = new PHPWord_Style_Font(); + + $attributes = array( + 'name' => 'Times New Roman', + 'size' => 9, + 'bold' => true, + 'italic' => true, + 'superScript' => true, + 'subScript' => true, + 'underline' => PHPWord_Style_Font::UNDERLINE_HEAVY, + 'strikethrough' => true, + 'color' => '999999', + 'fgColor' => '999999', + ); + foreach ($attributes as $key => $value) { + $get = "get{$key}"; + $object->setStyleValue("_$key", $value); + $this->assertEquals($value, $object->$get()); + } + } + + public function testLineHeight() + { + $PHPWord = new PHPWord(); + $section = $PHPWord->createSection(); + + // Test style array + $text = $section->addText('This is a test', array( + 'line-height' => 2.0 + )); + + $doc = TestHelperDOCX::getDocument($PHPWord); + $element = $doc->getElement('/w:document/w:body/w:p/w:pPr/w:spacing'); + + $lineHeight = $element->getAttribute('w:line'); + $lineRule = $element->getAttribute('w:lineRule'); + + $this->assertEquals(480, $lineHeight); + $this->assertEquals('auto', $lineRule); + + // Test setter + $text->getFontStyle()->setLineHeight(3.0); + $doc = TestHelperDOCX::getDocument($PHPWord); + $element = $doc->getElement('/w:document/w:body/w:p/w:pPr/w:spacing'); + + $lineHeight = $element->getAttribute('w:line'); + $lineRule = $element->getAttribute('w:lineRule'); + + $this->assertEquals(720, $lineHeight); + $this->assertEquals('auto', $lineRule); + } +} diff --git a/Tests/PHPWord/Style/ImageTest.php b/Tests/PHPWord/Style/ImageTest.php new file mode 100644 index 0000000000..7e7b38881a --- /dev/null +++ b/Tests/PHPWord/Style/ImageTest.php @@ -0,0 +1,68 @@ + 200, + 'height' => 200, + 'align' => 'left', + 'marginTop' => 240, + 'marginLeft' => 240, + 'wrappingStyle' => 'inline', + ); + foreach ($properties as $key => $value) { + $set = "set{$key}"; + $get = "get{$key}"; + $object->$set($value); + $this->assertEquals($value, $object->$get()); + } + } + + /** + * Test setStyleValue method + */ + public function testSetStyleValue() + { + $object = new PHPWord_Style_Image(); + + $properties = array( + 'width' => 200, + 'height' => 200, + 'align' => 'left', + 'marginTop' => 240, + 'marginLeft' => 240, + ); + foreach ($properties as $key => $value) { + $get = "get{$key}"; + $object->setStyleValue("_{$key}", $value); + $this->assertEquals($value, $object->$get()); + } + } + + /** + * Test setWrappingStyle exception + * + * @expectedException InvalidArgumentException + */ + public function testSetWrappingStyleException() + { + $object = new PHPWord_Style_Image(); + $object->setWrappingStyle('foo'); + } +} diff --git a/Tests/PHPWord/Style/ListItemTest.php b/Tests/PHPWord/Style/ListItemTest.php new file mode 100644 index 0000000000..890f468347 --- /dev/null +++ b/Tests/PHPWord/Style/ListItemTest.php @@ -0,0 +1,48 @@ +assertEquals($value, $object->getListType()); + } + + /** + * Test set style value + */ + public function testSetStyleValue() + { + $object = new PHPWord_Style_ListItem(); + + $value = PHPWord_Style_ListItem::TYPE_ALPHANUM; + $object->setStyleValue('_listType', $value); + $this->assertEquals($value, $object->getListType()); + } + + /** + * Test list type + */ + public function testListType() + { + $object = new PHPWord_Style_ListItem(); + + $value = PHPWord_Style_ListItem::TYPE_ALPHANUM; + $object->setListType($value); + $this->assertEquals($value, $object->getListType()); + } +} diff --git a/Tests/PHPWord/Style/ParagraphTest.php b/Tests/PHPWord/Style/ParagraphTest.php new file mode 100644 index 0000000000..ff084a5716 --- /dev/null +++ b/Tests/PHPWord/Style/ParagraphTest.php @@ -0,0 +1,135 @@ + null, + 'widowControl' => true, + 'keepNext' => false, + 'keepLines' => false, + 'pageBreakBefore' => false, + ); + foreach ($attributes as $key => $default) { + $get = "get{$key}"; + $object->setStyleValue("_$key", null); + $this->assertEquals($default, $object->$get()); + $object->setStyleValue("_$key", ''); + $this->assertEquals($default, $object->$get()); + } + } + + /** + * Test setting style values with normal value + */ + public function testSetStyleValueNormal() + { + $object = new PHPWord_Style_Paragraph(); + + $attributes = array( + 'align' => 'justify', + 'spaceAfter' => 240, + 'spaceBefore' => 240, + 'indent' => 1, + 'hanging' => 1, + 'spacing' => 120, + 'basedOn' => 'Normal', + 'next' => 'Normal', + 'widowControl' => false, + 'keepNext' => true, + 'keepLines' => true, + 'pageBreakBefore' => true, + ); + foreach ($attributes as $key => $value) { + $get = "get{$key}"; + $object->setStyleValue("_$key", $value); + if ($key == 'align') { + if ($value == 'justify') { + $value = 'both'; + } + } elseif ($key == 'indent' || $key == 'hanging') { + $value = $value * 720; + } elseif ($key == 'spacing') { + $value += 240; + } + $this->assertEquals($value, $object->$get()); + } + } + + /** + * Test tabs + */ + public function testTabs() + { + $object = new PHPWord_Style_Paragraph(); + $object->setTabs(array( + new PHPWord_Style_Tab('left', 1550), + new PHPWord_Style_Tab('right', 5300), + )); + $this->assertInstanceOf('PHPWord_Style_Tabs', $object->getTabs()); + } + + public function testLineHeight() + { + $PHPWord = new PHPWord(); + $section = $PHPWord->createSection(); + + // Test style array + $text = $section->addText('This is a test', array(), array( + 'line-height' => 2.0 + )); + + $doc = TestHelperDOCX::getDocument($PHPWord); + $element = $doc->getElement('/w:document/w:body/w:p/w:pPr/w:spacing'); + + $lineHeight = $element->getAttribute('w:line'); + $lineRule = $element->getAttribute('w:lineRule'); + + $this->assertEquals(480, $lineHeight); + $this->assertEquals('auto', $lineRule); + + // Test setter + $text->getParagraphStyle()->setLineHeight(3.0); + $doc = TestHelperDOCX::getDocument($PHPWord); + $element = $doc->getElement('/w:document/w:body/w:p/w:pPr/w:spacing'); + + $lineHeight = $element->getAttribute('w:line'); + $lineRule = $element->getAttribute('w:lineRule'); + + $this->assertEquals(720, $lineHeight); + $this->assertEquals('auto', $lineRule); + } + + /** + * Test setLineHeight validation + */ + public function testLineHeightValidation() + { + $object = new PHPWord_Style_Paragraph(); + $object->setLineHeight('12.5pt'); + $this->assertEquals(12.5, $object->getLineHeight()); + } +} diff --git a/Tests/PHPWord/Style/RowTest.php b/Tests/PHPWord/Style/RowTest.php new file mode 100644 index 0000000000..cbbecfbc09 --- /dev/null +++ b/Tests/PHPWord/Style/RowTest.php @@ -0,0 +1,40 @@ + true, + 'cantSplit' => false, + ); + foreach ($properties as $key => $value) { + // set/get + $set = "set{$key}"; + $get = "get{$key}"; + $expected = $value ? 1 : 0; + $object->$set($value); + $this->assertEquals($expected, $object->$get()); + + // setStyleValue + $value = !$value; + $expected = $value ? 1 : 0; + $object->setStyleValue("_{$key}", $value); + $this->assertEquals($expected, $object->$get()); + } + } +} diff --git a/Tests/PHPWord/Style/TOCTest.php b/Tests/PHPWord/Style/TOCTest.php new file mode 100644 index 0000000000..4607ba37aa --- /dev/null +++ b/Tests/PHPWord/Style/TOCTest.php @@ -0,0 +1,39 @@ + 9062, + 'tabLeader' => PHPWord_Style_TOC::TABLEADER_DOT, + 'indent' => 200, + ); + foreach ($properties as $key => $value) { + // set/get + $set = "set{$key}"; + $get = "get{$key}"; + $object->$set($value); + $this->assertEquals($value, $object->$get()); + + // setStyleValue + $object->setStyleValue("_{$key}", null); + $this->assertEquals(null, $object->$get()); + } + } +} diff --git a/Tests/PHPWord/Style/TableFullTest.php b/Tests/PHPWord/Style/TableFullTest.php new file mode 100644 index 0000000000..7f7b77324b --- /dev/null +++ b/Tests/PHPWord/Style/TableFullTest.php @@ -0,0 +1,133 @@ + 'FF0000'); + $styleFirstRow = array('borderBottomSize' => 3); + + $object = new PHPWord_Style_TableFull($styleTable, $styleFirstRow); + $this->assertEquals('FF0000', $object->getBgColor()); + + $firstRow = $object->getFirstRow(); + $this->assertInstanceOf('PHPWord_Style_TableFull', $firstRow); + $this->assertEquals(3, $firstRow->getBorderBottomSize()); + } + + /** + * Test setting style with normal value + */ + public function testSetGetNormal() + { + $object = new PHPWord_Style_TableFull(); + + $attributes = array( + 'bgColor' => 'FF0000', + 'borderTopSize' => 4, + 'borderTopColor' => 'FF0000', + 'borderLeftSize' => 4, + 'borderLeftColor' => 'FF0000', + 'borderRightSize' => 4, + 'borderRightColor' => 'FF0000', + 'borderBottomSize' => 4, + 'borderBottomColor' => 'FF0000', + 'borderInsideHSize' => 4, + 'borderInsideHColor' => 'FF0000', + 'borderInsideVSize' => 4, + 'borderInsideVColor' => 'FF0000', + 'cellMarginTop' => 240, + 'cellMarginLeft' => 240, + 'cellMarginRight' => 240, + 'cellMarginBottom' => 240, + ); + foreach ($attributes as $key => $value) { + $set = "set{$key}"; + $get = "get{$key}"; + $object->$set($value); + $this->assertEquals($value, $object->$get()); + } + } + + /** + * Test border color + * + * Set border color and test if each part has the same color + * While looping, push values array to be asserted with getBorderColor + */ + public function testBorderColor() + { + $object = new PHPWord_Style_TableFull(); + $parts = array('Top', 'Left', 'Right', 'Bottom', 'InsideH', 'InsideV'); + + $value = 'FF0000'; + $object->setBorderColor($value); + foreach ($parts as $part) { + $get = "getBorder{$part}Color"; + $values[] = $value; + $this->assertEquals($value, $object->$get()); + } + $this->assertEquals($values, $object->getBorderColor()); + } + + /** + * Test border size + * + * Set border size and test if each part has the same size + * While looping, push values array to be asserted with getBorderSize + * Value is in eights of a point, i.e. 4 / 8 = .5pt + */ + public function testBorderSize() + { + $object = new PHPWord_Style_TableFull(); + $parts = array('Top', 'Left', 'Right', 'Bottom', 'InsideH', 'InsideV'); + + $value = 4; + $object->setBorderSize($value); + foreach ($parts as $part) { + $get = "getBorder{$part}Size"; + $values[] = $value; + $this->assertEquals($value, $object->$get()); + } + $this->assertEquals($values, $object->getBorderSize()); + } + + /** + * Test cell margin + * + * Set cell margin and test if each part has the same margin + * While looping, push values array to be asserted with getCellMargin + * Value is in twips + */ + public function testCellMargin() + { + $object = new PHPWord_Style_TableFull(); + $parts = array('Top', 'Left', 'Right', 'Bottom'); + + $value = 240; + $object->setCellMargin($value); + foreach ($parts as $part) { + $get = "getCellMargin{$part}"; + $values[] = $value; + $this->assertEquals($value, $object->$get()); + } + $this->assertEquals($values, $object->getCellMargin()); + } +} diff --git a/Tests/PHPWord/Style/TableTest.php b/Tests/PHPWord/Style/TableTest.php new file mode 100644 index 0000000000..439aa5ae8b --- /dev/null +++ b/Tests/PHPWord/Style/TableTest.php @@ -0,0 +1,51 @@ +setStyleValue($property, $value); + $this->assertEquals($value, $object->$get()); + } + } + + /** + * Test cell margin + */ + public function testCellMargin() + { + $object = new PHPWord_Style_Table(); + $parts = array('Top', 'Left', 'Right', 'Bottom'); + + // Set cell margin and test if each part has the same margin + // While looping, push values array to be asserted with getCellMargin + $value = 240; // In twips + foreach ($parts as $part) { + $set = "setCellMargin{$part}"; + $get = "getCellMargin{$part}"; + $values[] = $value; + $object->$set($value); + $this->assertEquals($value, $object->$get()); + } + $this->assertEquals($values, $object->getCellMargin()); + } +} diff --git a/Tests/PHPWord/Style/TabsTest.php b/Tests/PHPWord/Style/TabsTest.php new file mode 100644 index 0000000000..7579ae6de0 --- /dev/null +++ b/Tests/PHPWord/Style/TabsTest.php @@ -0,0 +1,44 @@ +addParagraphStyle('tabbed', array( + 'tabs' => array( + new PHPWord_Style_Tab('left', 1440, 'dot'), + ) + )); + $doc = TestHelperDOCX::getDocument($PHPWord); + $file = 'word/styles.xml'; + $path = '/w:styles/w:style[@w:styleId="tabbed"]/w:pPr/w:tabs/w:tab[1]'; + $element = $doc->getElement($path, $file); + $this->assertEquals('left', $element->getAttribute('w:val')); + $this->assertEquals(1440, $element->getAttribute('w:pos')); + $this->assertEquals('dot', $element->getAttribute('w:leader')); + } +} diff --git a/Tests/PHPWord/StyleTest.php b/Tests/PHPWord/StyleTest.php new file mode 100644 index 0000000000..9e442cb13e --- /dev/null +++ b/Tests/PHPWord/StyleTest.php @@ -0,0 +1,44 @@ + 'center'); + $font = array('italic' => true); + $table = array('bgColor' => 'CCCCCC'); + $styles = array('Paragraph' => 'Paragraph', 'Font' => 'Font', + 'Link' => 'Font', 'Table' => 'TableFull', + 'Heading_1' => 'Font', 'Normal' => 'Paragraph'); + $elementCount = 6; + PHPWord_Style::addParagraphStyle('Paragraph', $paragraph); + PHPWord_Style::addFontStyle('Font', $font); + PHPWord_Style::addLinkStyle('Link', $font); + PHPWord_Style::addTableStyle('Table', $table); + PHPWord_Style::addTitleStyle(1, $font); + PHPWord_Style::setDefaultParagraphStyle($paragraph); + + $this->assertEquals($elementCount, count(PHPWord_Style::getStyles())); + foreach ($styles as $name => $style) { + $expected = "PHPWord_Style_{$style}"; + $this->assertInstanceOf($expected, PHPWord_Style::getStyle($name)); + } + $this->assertNull(PHPWord_Style::getStyle('Unknown')); + } +} diff --git a/Tests/PHPWord/TOCTest.php b/Tests/PHPWord/TOCTest.php new file mode 100644 index 0000000000..d4503da5fd --- /dev/null +++ b/Tests/PHPWord/TOCTest.php @@ -0,0 +1,75 @@ + 9062, + 'tabLeader' => PHPWord_Style_TOC::TABLEADER_DOT, + 'indent' => 200, + ); + $object = new PHPWord_TOC( + array('size' => 11), + array('tabPos' => $expected['tabPos']) + ); + $tocStyle = $object->getStyleTOC(); + + $this->assertInstanceOf('PHPWord_Style_TOC', $tocStyle); + $this->assertInstanceOf('PHPWord_Style_Font', $object->getStyleFont()); + + foreach ($expected as $key => $value) { + $method = "get{$key}"; + $this->assertEquals($value, $tocStyle->$method()); + } + } + + /** + * @covers PHPWord_TOC::addTitle + * @covers PHPWord_TOC::getTitles + */ + public function testAddAndGetTitle() + { + // Prepare variables + $titleCount = 3; + $anchor = '_Toc' . (252634154 + $titleCount); + $bookmark = $titleCount - 1; + $titles = array( + 'Heading 1' => 1, + 'Heading 2' => 2, + 'Heading 3' => 3, + ); + + // @covers PHPWord_TOC::addTitle + foreach ($titles as $text => $depth) { + $response = PHPWord_TOC::addTitle($text, $depth); + } + $this->assertEquals($anchor, $response[0]); + $this->assertEquals($bookmark, $response[1]); + + // @covers PHPWord_TOC::getTitles + $i = 0; + $savedTitles = PHPWord_TOC::getTitles(); + foreach ($titles as $text => $depth) { + $this->assertEquals($text, $savedTitles[$i]['text']); + $this->assertEquals($depth, $savedTitles[$i]['depth']); + $i++; + } + } +} diff --git a/Tests/PHPWord/TemplateTest.php b/Tests/PHPWord/TemplateTest.php new file mode 100644 index 0000000000..872ab182e4 --- /dev/null +++ b/Tests/PHPWord/TemplateTest.php @@ -0,0 +1,175 @@ +load( + \join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'xsl', 'remove_tables_by_needle.xsl') + ) + ); + foreach (array('${employee.', '${scoreboard.') as $needle) { + $document->applyXslStyleSheet($xslDOMDocument, array('needle' => $needle)); + } + + $documentFqfn = $document->save(); + + $this->assertNotEmpty($documentFqfn, 'FQFN of the saved document is empty.'); + $this->assertFileExists($documentFqfn, "The saved document \"{$documentFqfn}\" doesn't exist."); + + $templateZip = new \ZipArchive(); + $templateZip->open($templateFqfn); + $templateXml = $templateZip->getFromName('word/document.xml'); + if ($templateZip->close() === false) { + throw new \Exception("Could not close zip file \"{$templateZip}\"."); + } + + $documentZip = new \ZipArchive(); + $documentZip->open($documentFqfn); + $documentXml = $documentZip->getFromName('word/document.xml'); + if ($documentZip->close() === false) { + throw new \Exception("Could not close zip file \"{$documentZip}\"."); + } + + $this->assertNotEquals($documentXml, $templateXml); + + return $documentFqfn; + } + + /** + * @covers ::applyXslStyleSheet + * @depends testTemplateCanBeSavedInTemporaryLocation + * @test + */ + final public function testXslStyleSheetCanBeApplied($actualDocumentFqfn) + { + $expectedDocumentFqfn = \join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'documents', 'without_table_macros.docx') + ); + + $actualDocumentZip = new \ZipArchive(); + $actualDocumentZip->open($actualDocumentFqfn); + $actualDocumentXml = $actualDocumentZip->getFromName('word/document.xml'); + if ($actualDocumentZip->close() === false) { + throw new \Exception("Could not close zip file \"{$actualDocumentFqfn}\"."); + } + + $expectedDocumentZip = new \ZipArchive(); + $expectedDocumentZip->open($expectedDocumentFqfn); + $expectedDocumentXml = $expectedDocumentZip->getFromName('word/document.xml'); + if ($expectedDocumentZip->close() === false) { + throw new \Exception("Could not close zip file \"{$expectedDocumentFqfn}\"."); + } + + $this->assertXmlStringEqualsXmlString($expectedDocumentXml, $actualDocumentXml); + } + + /** + * @covers ::applyXslStyleSheet + * @expectedException Exception + * @expectedExceptionMessage Could not set values for the given XSL style sheet parameters. + * @test + */ + final public function testXslStyleSheetCanNotBeAppliedOnFailureOfSettingParameterValue() + { + $template = new PHPWord_Template( + \join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'templates', 'blank.docx') + ) + ); + + $xslDOMDocument = new \DOMDocument(); + $xslDOMDocument->load( + \join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'xsl', 'passthrough.xsl') + ) + ); + + /* + * We have to use error control below, because XSLTProcessor::setParameter omits warning on failure. + * This warning fails the test. + */ + @$template->applyXslStyleSheet($xslDOMDocument, array(1 => 'somevalue')); + } + + /** + * @covers ::applyXslStyleSheet + * @expectedException Exception + * @expectedExceptionMessage Could not load XML from the given template. + * @test + */ + final public function testXslStyleSheetCanNotBeAppliedOnFailureOfLoadingXmlFromTemplate() + { + $template = new PHPWord_Template( + \join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'templates', 'corrupted_main_document_part.docx') + ) + ); + + $xslDOMDocument = new \DOMDocument(); + $xslDOMDocument->load( + \join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'xsl', 'passthrough.xsl') + ) + ); + + /* + * We have to use error control below, because DOMDocument::loadXML omits warning on failure. + * This warning fails the test. + */ + @$template->applyXslStyleSheet($xslDOMDocument); + } + + /** + * @covers ::setValue + * @covers ::getVariables + * @covers ::cloneRow + * @covers ::saveAs + */ + public function testCloneRow() + { + $template = \join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'templates', 'clone-row.docx') + ); + $expectedVar = array('tableHeader', 'userId', 'userName', 'userLocation'); + $docName = 'clone-test-result.docx'; + + $PHPWord = new PHPWord(); + $document = $PHPWord->loadTemplate($template); + $actualVar = $document->getVariables(); + $document->cloneRow('userId', 1); + $document->setValue('userId#1', 'Test'); + $document->saveAs($docName); + $docFound = file_exists($docName); + unlink($docName); + + $this->assertEquals($expectedVar, $actualVar); + $this->assertTrue($docFound); + } +} diff --git a/Tests/PHPWord/Writer/ODText/ContentTest.php b/Tests/PHPWord/Writer/ODText/ContentTest.php new file mode 100644 index 0000000000..63b84d7553 --- /dev/null +++ b/Tests/PHPWord/Writer/ODText/ContentTest.php @@ -0,0 +1,65 @@ + + */ + public function testWriteContent() + { + $imageSrc = \join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'images', 'PHPWord.png') + ); + $objectSrc = \join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'documents', 'sheet.xls') + ); + $expected = 'Expected'; + + $PHPWord = new PHPWord(); + $PHPWord->setDefaultFontName('Verdana'); + $PHPWord->addFontStyle('Font', array('size' => 11)); + $PHPWord->addParagraphStyle('Paragraph', array('align' => 'center')); + $section = $PHPWord->createSection(); + $section->addText($expected); + $section->addText('Test font style', 'Font'); + $section->addText('Test paragraph style', null, 'Paragraph'); + $section->addTextBreak(); + $section->addLink('http://test.com', 'Test link'); + $section->addTitle('Test title', 1); + $section->addPageBreak(); + $section->addTable(); + $section->addListItem('Test list item'); + $section->addImage($imageSrc); + $section->addObject($objectSrc); + $section->addTOC(); + $textrun = $section->createTextRun(); + $textrun->addText('Test text run'); + $doc = TestHelperDOCX::getDocument($PHPWord, 'ODText'); + + $element = "/office:document-content/office:body/office:text/text:p"; + $this->assertEquals($expected, $doc->getElement($element, 'content.xml')->nodeValue); + } +} diff --git a/Tests/PHPWord/Writer/ODTextTest.php b/Tests/PHPWord/Writer/ODTextTest.php new file mode 100644 index 0000000000..ef92d249fd --- /dev/null +++ b/Tests/PHPWord/Writer/ODTextTest.php @@ -0,0 +1,154 @@ +assertInstanceOf('PHPWord', $object->getPHPWord()); + $this->assertInstanceOf("PHPWord_HashTable", $object->getDrawingHashTable()); + + $this->assertEquals('./', $object->getDiskCachingDirectory()); + $writerParts = array('Content', 'Manifest', 'Meta', 'Mimetype', 'Styles'); + foreach ($writerParts as $part) { + $this->assertInstanceOf( + "PHPWord_Writer_ODText_{$part}", + $object->getWriterPart($part) + ); + $this->assertInstanceOf( + "PHPWord_Writer_ODText", + $object->getWriterPart($part)->getParentWriter() + ); + } + } + + /** + * @covers ::getPHPWord + * @expectedException Exception + * @expectedExceptionMessage No PHPWord assigned. + */ + public function testConstructWithNull() + { + $object = new PHPWord_Writer_ODText(); + $object->getPHPWord(); + } + + /** + * @covers ::save + */ + public function testSave() + { + $imageSrc = \join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'images', 'PHPWord.png') + ); + $objectSrc = \join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'documents', 'sheet.xls') + ); + $file = \join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'temp.odt') + ); + + $phpWord = new PHPWord(); + $phpWord->addFontStyle('Font', array('size' => 11)); + $phpWord->addParagraphStyle('Paragraph', array('align' => 'center')); + $section = $phpWord->createSection(); + $section->addText('Test 1', 'Font'); + $section->addTextBreak(); + $section->addText('Test 2', null, 'Paragraph'); + $section->addLink('http://test.com'); + $section->addTitle('Test', 1); + $section->addPageBreak(); + $section->addTable(); + $section->addListItem('Test'); + $section->addImage($imageSrc); + $section->addObject($objectSrc); + $section->addTOC(); + $section = $phpWord->createSection(); + $textrun = $section->createTextRun(); + $textrun->addText('Test 3'); + $writer = new PHPWord_Writer_ODText($phpWord); + $writer->save($file); + + $this->assertTrue(file_exists($file)); + + unlink($file); + } + + /** + * @covers ::save + * @todo Haven't got any method to test this + */ + public function testSavePhpOutput() + { + $phpWord = new PHPWord(); + $section = $phpWord->createSection(); + $section->addText('Test'); + $writer = new PHPWord_Writer_ODText($phpWord); + $writer->save('php://output'); + } + + /** + * @covers ::save + * @expectedException Exception + * @expectedExceptionMessage PHPWord object unassigned. + */ + public function testSaveException() + { + $writer = new PHPWord_Writer_ODText(); + $writer->save(); + } + + /** + * @covers ::getWriterPart + */ + public function testGetWriterPartNull() + { + $object = new PHPWord_Writer_ODText(); + $this->assertNull($object->getWriterPart('foo')); + } + + /** + * @covers ::setUseDiskCaching + * @covers ::getUseDiskCaching + */ + public function testSetGetUseDiskCaching() + { + $object = new PHPWord_Writer_ODText(); + $object->setUseDiskCaching(true, PHPWORD_TESTS_DIR_ROOT); + $this->assertTrue($object->getUseDiskCaching()); + $this->assertEquals(PHPWORD_TESTS_DIR_ROOT, $object->getDiskCachingDirectory()); + } + + /** + * @covers ::setUseDiskCaching + * @expectedException Exception + */ + public function testSetUseDiskCachingException() + { + $dir = \join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, 'foo') + ); + + $object = new PHPWord_Writer_ODText($phpWord); + $object->setUseDiskCaching(true, $dir); + } +} diff --git a/Tests/PHPWord/Writer/RTFTest.php b/Tests/PHPWord/Writer/RTFTest.php new file mode 100644 index 0000000000..d071def78f --- /dev/null +++ b/Tests/PHPWord/Writer/RTFTest.php @@ -0,0 +1,107 @@ +assertInstanceOf('PHPWord', $object->getPHPWord()); + $this->assertInstanceOf("PHPWord_HashTable", $object->getDrawingHashTable()); + } + + /** + * covers ::__construct + * @expectedException Exception + * @expectedExceptionMessage No PHPWord assigned. + */ + public function testConstructWithNull() + { + $object = new PHPWord_Writer_RTF(); + $object->getPHPWord(); + } + + /** + * @covers ::save + * @todo Haven't got any method to test this + */ + public function testSavePhpOutput() + { + $phpWord = new PHPWord(); + $section = $phpWord->createSection(); + $section->addText('Test'); + $writer = new PHPWord_Writer_RTF($phpWord); + $writer->save('php://output'); + } + + /** + * @covers ::save + * @expectedException Exception + * @expectedExceptionMessage PHPWord object unassigned. + */ + public function testSaveException() + { + $writer = new PHPWord_Writer_RTF(); + $writer->save(); + } + + /** + * @covers ::save + * @covers :: + */ + public function testSave() + { + $imageSrc = \join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'images', 'PHPWord.png') + ); + $objectSrc = \join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'documents', 'sheet.xls') + ); + $file = \join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'temp.rtf') + ); + + $phpWord = new PHPWord(); + $phpWord->addFontStyle('Font', array('size' => 11)); + $phpWord->addParagraphStyle('Paragraph', array('align' => 'center')); + $section = $phpWord->createSection(); + $section->addText('Test 1', 'Font'); + $section->addTextBreak(); + $section->addText('Test 2', null, 'Paragraph'); + $section->addLink('http://test.com'); + $section->addTitle('Test', 1); + $section->addPageBreak(); + $section->addTable(); + $section->addListItem('Test'); + $section->addImage($imageSrc); + $section->addObject($objectSrc); + $section->addTOC(); + $section = $phpWord->createSection(); + $textrun = $section->createTextRun(); + $textrun->addText('Test 3'); + $textrun->addTextBreak(); + $writer = new PHPWord_Writer_RTF($phpWord); + $writer->save($file); + + $this->assertTrue(file_exists($file)); + + unlink($file); + } +} diff --git a/Tests/PHPWord/Writer/Word2007/BaseTest.php b/Tests/PHPWord/Writer/Word2007/BaseTest.php index 8788af8b3e..fde6e30b20 100644 --- a/Tests/PHPWord/Writer/Word2007/BaseTest.php +++ b/Tests/PHPWord/Writer/Word2007/BaseTest.php @@ -1,62 +1,275 @@ createSection(); - $section->addImage( - PHPWORD_TESTS_DIR_ROOT . '/_files/images/earth.jpg', - array( - 'marginTop' => -1, - 'marginLeft' => -1, - 'wrappingStyle' => 'behind' - ) - ); - - $doc = TestHelperDOCX::getDocument($PHPWord); - $element = $doc->getElement('/w:document/w:body/w:p/w:r/w:pict/v:shape'); - - $style = $element->getAttribute('style'); - - $this->assertRegExp('/z\-index:\-[0-9]*/', $style); - $this->assertRegExp('/position:absolute;/', $style); - } - - public function testWriteParagraphStyle_Align() - { - $PHPWord = new PHPWord(); - $section = $PHPWord->createSection(); - - $section->addText('This is my text', null, array('align' => 'right')); - - $doc = TestHelperDOCX::getDocument($PHPWord); - $element = $doc->getElement('/w:document/w:body/w:p/w:pPr/w:jc'); - - $this->assertEquals('right', $element->getAttribute('w:val')); - } - - public function testWriteCellStyle_CellGridSpan() - { +class BaseTest extends \PHPUnit_Framework_TestCase +{ + /** + * Executed before each method of the class + */ + public function tearDown() + { + TestHelperDOCX::clear(); + } + + /** + * covers ::_writeText + */ + public function testWriteText() + { + $rStyle = 'rStyle'; + $pStyle = 'pStyle'; + + $PHPWord = new PHPWord(); + $PHPWord->addFontStyle($rStyle, array('bold' => true)); + $PHPWord->addParagraphStyle($pStyle, array('hanging' => 120, 'indent' => 120)); + $section = $PHPWord->createSection(); + $section->addText('Test', $rStyle, $pStyle); + $doc = TestHelperDOCX::getDocument($PHPWord); + + $element = "/w:document/w:body/w:p/w:r/w:rPr/w:rStyle"; + $this->assertEquals($rStyle, $doc->getElementAttribute($element, 'w:val')); + $element = "/w:document/w:body/w:p/w:pPr/w:pStyle"; + $this->assertEquals($pStyle, $doc->getElementAttribute($element, 'w:val')); + } + + /** + * covers ::_writeTextRun + */ + public function testWriteTextRun() + { + $pStyle = 'pStyle'; + $aStyle = array('align' => 'justify', 'spaceBefore' => 120, 'spaceAfter' => 120); + $imageSrc = join( + DIRECTORY_SEPARATOR, + array(PHPWORD_TESTS_DIR_ROOT, '_files', 'images', 'earth.jpg') + ); + + $PHPWord = new PHPWord(); + $PHPWord->addParagraphStyle($pStyle, $aStyle); + $section = $PHPWord->createSection('Test'); + $textrun = $section->createTextRun($pStyle); + $textrun->addText('Test'); + $textrun->addTextBreak(); + $textrun = $section->createTextRun($aStyle); + $textrun->addLink('http://test.com'); + $textrun->addImage($imageSrc); + $doc = TestHelperDOCX::getDocument($PHPWord); + + $parent = "/w:document/w:body/w:p"; + $this->assertTrue($doc->elementExists("{$parent}/w:pPr/w:pStyle[@w:val='{$pStyle}']")); + } + + /** + * covers ::_writeLink + */ + public function testWriteLink() + { + $PHPWord = new PHPWord(); + $section = $PHPWord->createSection(); + + $expected = 'PHPWord'; + $section->addLink('http://github.com/phpoffice/phpword', $expected); + + $doc = TestHelperDOCX::getDocument($PHPWord); + $element = $doc->getElement('/w:document/w:body/w:p/w:hyperlink/w:r/w:t'); + + $this->assertEquals($expected, $element->nodeValue); + } + + /** + * covers ::_writePreserveText + */ + public function testWritePreserveText() + { + $PHPWord = new PHPWord(); + $section = $PHPWord->createSection(); + $footer = $section->createFooter(); + + $footer->addPreserveText('{PAGE}'); + + $doc = TestHelperDOCX::getDocument($PHPWord); + $preserve = $doc->getElement("w:p/w:r[2]/w:instrText", 'word/footer1.xml'); + + $this->assertEquals('PAGE', $preserve->nodeValue); + $this->assertEquals('preserve', $preserve->getAttribute('xml:space')); + } + /** + * covers ::_writeTextBreak + */ + public function testWriteTextBreak() + { + $fArray = array('size' => 12); + $pArray = array('spacing' => 240); + $fName = 'fStyle'; + $pName = 'pStyle'; + + $PHPWord = new PHPWord(); + $PHPWord->addFontStyle($fName, $fArray); + $PHPWord->addParagraphStyle($pName, $pArray); + $section = $PHPWord->createSection(); + $section->addTextBreak(); + $section->addTextBreak(1, $fArray, $pArray); + $section->addTextBreak(1, $fName, $pName); + $doc = TestHelperDOCX::getDocument($PHPWord); + + $element = $doc->getElement('/w:document/w:body/w:p/w:pPr/w:rPr/w:rStyle'); + $this->assertEquals($fName, $element->getAttribute('w:val')); + $element = $doc->getElement('/w:document/w:body/w:p/w:pPr/w:pStyle'); + $this->assertEquals($pName, $element->getAttribute('w:val')); + } + + /** + * covers ::_writeParagraphStyle + */ + public function testWriteParagraphStyleAlign() + { + $PHPWord = new PHPWord(); + $section = $PHPWord->createSection(); + + $section->addText('This is my text', null, array('align' => 'right')); + + $doc = TestHelperDOCX::getDocument($PHPWord); + $element = $doc->getElement('/w:document/w:body/w:p/w:pPr/w:jc'); + + $this->assertEquals('right', $element->getAttribute('w:val')); + } + + /** + * covers ::_writeParagraphStyle + */ + public function testWriteParagraphStylePagination() + { + // Create the doc + $PHPWord = new PHPWord(); + $section = $PHPWord->createSection(); + $attributes = array( + 'widowControl' => false, + 'keepNext' => true, + 'keepLines' => true, + 'pageBreakBefore' => true, + ); + foreach ($attributes as $attribute => $value) { + $section->addText('Test', null, array($attribute => $value)); + } + $doc = TestHelperDOCX::getDocument($PHPWord); + + // Test the attributes + $i = 0; + foreach ($attributes as $key => $value) { + $i++; + $path = "/w:document/w:body/w:p[{$i}]/w:pPr/w:{$key}"; + $element = $doc->getElement($path); + $expected = $value ? 1 : 0; + $this->assertEquals($expected, $element->getAttribute('w:val')); + } + } + + /** + * covers ::_writeTextStyle + */ + public function testWriteFontStyle() + { + $PHPWord = new PHPWord(); + $styles['name'] = 'Verdana'; + $styles['size'] = 14; + $styles['bold'] = true; + $styles['italic'] = true; + $styles['underline'] = 'dash'; + $styles['strikethrough'] = true; + $styles['superScript'] = true; + $styles['color'] = 'FF0000'; + $styles['fgColor'] = 'yellow'; + + $section = $PHPWord->createSection(); + $section->addText('Test', $styles); + $doc = TestHelperDOCX::getDocument($PHPWord); + + $parent = '/w:document/w:body/w:p/w:r/w:rPr'; + $this->assertEquals($styles['name'], $doc->getElementAttribute("{$parent}/w:rFonts", 'w:ascii')); + $this->assertEquals($styles['size'] * 2, $doc->getElementAttribute("{$parent}/w:sz", 'w:val')); + $this->assertTrue($doc->elementExists("{$parent}/w:b")); + $this->assertTrue($doc->elementExists("{$parent}/w:i")); + $this->assertEquals($styles['underline'], $doc->getElementAttribute("{$parent}/w:u", 'w:val')); + $this->assertTrue($doc->elementExists("{$parent}/w:strike")); + $this->assertEquals('superscript', $doc->getElementAttribute("{$parent}/w:vertAlign", 'w:val')); + $this->assertEquals($styles['color'], $doc->getElementAttribute("{$parent}/w:color", 'w:val')); + $this->assertEquals($styles['fgColor'], $doc->getElementAttribute("{$parent}/w:highlight", 'w:val')); + } + + /** + * covers ::_writeTableStyle + */ + public function testWriteTableStyle() + { + $PHPWord = new PHPWord(); + $tWidth = 120; + $rHeight = 120; + $cWidth = 120; + $tStyles["cellMarginTop"] = 120; + $tStyles["cellMarginRight"] = 120; + $tStyles["cellMarginBottom"] = 120; + $tStyles["cellMarginLeft"] = 120; + $rStyles["tblHeader"] = true; + $rStyles["cantSplit"] = true; + $cStyles["valign"] = 'top'; + $cStyles["textDirection"] = 'btLr'; + $cStyles["bgColor"] = 'FF0000'; + $cStyles["borderTopSize"] = 120; + $cStyles["borderBottomSize"] = 120; + $cStyles["borderLeftSize"] = 120; + $cStyles["borderRightSize"] = 120; + $cStyles["borderTopColor"] = 'FF0000'; + $cStyles["borderBottomColor"] = 'FF0000'; + $cStyles["borderLeftColor"] = 'FF0000'; + $cStyles["borderRightColor"] = 'FF0000'; + + $section = $PHPWord->createSection(); + $table = $section->addTable($tStyles); + $table->setWidth = 100; + $table->addRow($rHeight, $rStyles); + $cell = $table->addCell($cWidth, $cStyles); + $cell->addText('Test'); + $cell->addTextBreak(); + $cell->addLink('http://google.com'); + $cell->addListItem('Test'); + $textrun = $cell->createTextRun(); + $textrun->addText('Test'); + + $doc = TestHelperDOCX::getDocument($PHPWord); + + $parent = '/w:document/w:body/w:tbl/w:tblPr/w:tblCellMar'; + $this->assertEquals($tStyles['cellMarginTop'], $doc->getElementAttribute("{$parent}/w:top", 'w:w')); + $this->assertEquals($tStyles['cellMarginRight'], $doc->getElementAttribute("{$parent}/w:right", 'w:w')); + $this->assertEquals($tStyles['cellMarginBottom'], $doc->getElementAttribute("{$parent}/w:bottom", 'w:w')); + $this->assertEquals($tStyles['cellMarginLeft'], $doc->getElementAttribute("{$parent}/w:right", 'w:w')); + + $parent = '/w:document/w:body/w:tbl/w:tr/w:trPr'; + $this->assertEquals($rHeight, $doc->getElementAttribute("{$parent}/w:trHeight", 'w:val')); + $this->assertEquals($rStyles['tblHeader'], $doc->getElementAttribute("{$parent}/w:tblHeader", 'w:val')); + $this->assertEquals($rStyles['cantSplit'], $doc->getElementAttribute("{$parent}/w:cantSplit", 'w:val')); + + $parent = '/w:document/w:body/w:tbl/w:tr/w:tc/w:tcPr'; + $this->assertEquals($cWidth, $doc->getElementAttribute("{$parent}/w:tcW", 'w:w')); + $this->assertEquals($cStyles['valign'], $doc->getElementAttribute("{$parent}/w:vAlign", 'w:val')); + $this->assertEquals($cStyles['textDirection'], $doc->getElementAttribute("{$parent}/w:textDirection", 'w:val')); + } + + /** + * covers ::_writeCellStyle + */ + public function testWriteCellStyleCellGridSpan() + { $PHPWord = new PHPWord(); $section = $PHPWord->createSection(); @@ -78,5 +291,65 @@ public function testWriteCellStyle_CellGridSpan() $this->assertEquals(5, $element->getAttribute('w:val')); } + + /** + * covers ::_writeImage + */ + public function testWriteImagePosition() + { + $PHPWord = new PHPWord(); + $section = $PHPWord->createSection(); + $section->addImage( + PHPWORD_TESTS_DIR_ROOT . '/_files/images/earth.jpg', + array( + 'marginTop' => -1, + 'marginLeft' => -1, + 'wrappingStyle' => 'behind' + ) + ); + + $doc = TestHelperDOCX::getDocument($PHPWord); + $element = $doc->getElement('/w:document/w:body/w:p/w:r/w:pict/v:shape'); + + $style = $element->getAttribute('style'); + + $this->assertRegExp('/z\-index:\-[0-9]*/', $style); + $this->assertRegExp('/position:absolute;/', $style); + } + + /** + * covers ::_writeWatermark + */ + public function testWriteWatermark() + { + $imageSrc = join( + DIRECTORY_SEPARATOR, + array(PHPWORD_TESTS_DIR_ROOT, '_files', 'images', 'earth.jpg') + ); + + $PHPWord = new PHPWord(); + $section = $PHPWord->createSection(); + $header = $section->createHeader(); + $header->addWatermark($imageSrc); + $doc = TestHelperDOCX::getDocument($PHPWord); + + $element = $doc->getElement("/w:document/w:body/w:sectPr/w:headerReference"); + $this->assertStringStartsWith("rId", $element->getAttribute('r:id')); + } + + /** + * covers ::_writeTitle + */ + public function testWriteTitle() + { + $PHPWord = new PHPWord(); + $PHPWord->addTitleStyle(1, array('bold' => true), array('spaceAfter' => 240)); + $PHPWord->createSection()->addTitle('Test', 1); + $doc = TestHelperDOCX::getDocument($PHPWord); + + $element = "/w:document/w:body/w:p/w:pPr/w:pStyle"; + $this->assertEquals('Heading1', $doc->getElementAttribute($element, 'w:val')); + $element = "/w:document/w:body/w:p/w:r/w:fldChar"; + $this->assertEquals('end', $doc->getElementAttribute($element, 'w:fldCharType')); + } } - \ No newline at end of file diff --git a/Tests/PHPWord/Writer/Word2007/DocumentTest.php b/Tests/PHPWord/Writer/Word2007/DocumentTest.php index 13d233cce9..fe854feebe 100644 --- a/Tests/PHPWord/Writer/Word2007/DocumentTest.php +++ b/Tests/PHPWord/Writer/Word2007/DocumentTest.php @@ -1,35 +1,87 @@ createSection(); - $section->getSettings()->setPageNumberingStart(2); - - $doc = TestHelperDOCX::getDocument($PHPWord); - $element = $doc->getElement('/w:document/w:body/w:sectPr/w:pgNumType'); - - $this->assertEquals(2, $element->getAttribute('w:start')); - } +class DocumentTest extends \PHPUnit_Framework_TestCase +{ + /** + * Executed before each method of the class + */ + public function tearDown() + { + TestHelperDOCX::clear(); + } + + public function testWriteEndSectionPageNumbering() + { + $PHPWord = new PHPWord(); + $section = $PHPWord->createSection(); + $section->getSettings()->setPageNumberingStart(2); + + $doc = TestHelperDOCX::getDocument($PHPWord); + $element = $doc->getElement('/w:document/w:body/w:sectPr/w:pgNumType'); + + $this->assertEquals(2, $element->getAttribute('w:start')); + } + + /** + * covers ::_writeTOC + * covers ::_writePageBreak + * covers ::_writeListItem + * covers ::_writeTitle + * covers ::_writeObject + */ + public function testElements() + { + $objectSrc = join( + DIRECTORY_SEPARATOR, + array(PHPWORD_TESTS_DIR_ROOT, '_files', 'documents', 'sheet.xls') + ); + + $PHPWord = new PHPWord(); + $PHPWord->addTitleStyle(1, array('color' => '333333', 'bold'=>true)); + $PHPWord->addTitleStyle(2, array('color'=>'666666')); + $section = $PHPWord->createSection(); + $section->addTOC(); + $section->addPageBreak(); + $section->addTitle('Title 1', 1); + $section->addListItem('List Item 1', 0); + $section->addListItem('List Item 2', 0); + $section->addListItem('List Item 3', 0); + $section = $PHPWord->createSection(); + $section->addTitle('Title 2', 2); + $section->addObject($objectSrc); + $doc = TestHelperDOCX::getDocument($PHPWord); + + // TOC + $element = $doc->getElement('/w:document/w:body/w:p[1]/w:pPr/w:tabs/w:tab'); + $this->assertEquals('right', $element->getAttribute('w:val')); + $this->assertEquals('dot', $element->getAttribute('w:leader')); + $this->assertEquals(9062, $element->getAttribute('w:pos')); + + // Page break + $element = $doc->getElement('/w:document/w:body/w:p[4]/w:r/w:br'); + $this->assertEquals('page', $element->getAttribute('w:type')); + + // Title + $element = $doc->getElement('/w:document/w:body/w:p[5]/w:pPr/w:pStyle'); + $this->assertEquals('Heading1', $element->getAttribute('w:val')); + + // List item + $element = $doc->getElement('/w:document/w:body/w:p[6]/w:pPr/w:numPr/w:numId'); + $this->assertEquals(3, $element->getAttribute('w:val')); + + // Object + $element = $doc->getElement('/w:document/w:body/w:p[11]/w:r/w:object/o:OLEObject'); + $this->assertEquals('Embed', $element->getAttribute('Type')); + } } - \ No newline at end of file diff --git a/Tests/PHPWord/Writer/Word2007/FootnotesTest.php b/Tests/PHPWord/Writer/Word2007/FootnotesTest.php new file mode 100644 index 0000000000..ea49bd6726 --- /dev/null +++ b/Tests/PHPWord/Writer/Word2007/FootnotesTest.php @@ -0,0 +1,34 @@ +createSection(); + $section->addText('Text'); + $footnote = $section->createFootnote(); + $footnote->addText('Footnote'); + $footnote->addLink('http://google.com'); + $doc = TestHelperDOCX::getDocument($PHPWord); + + $this->assertTrue($doc->elementExists("/w:document/w:body/w:p/w:r/w:footnoteReference")); + } +} diff --git a/Tests/PHPWord/Writer/Word2007/StylesTest.php b/Tests/PHPWord/Writer/Word2007/StylesTest.php new file mode 100644 index 0000000000..bcdc4b815d --- /dev/null +++ b/Tests/PHPWord/Writer/Word2007/StylesTest.php @@ -0,0 +1,71 @@ + 'both'); + $pBase = array('basedOn' => 'Normal'); + $pNew = array('basedOn' => 'Base Style', 'next' => 'Normal'); + $rStyle = array('size' => 20); + $tStyle = array( + 'bgColor' => 'FF0000', + 'cellMarginTop' => 120, + 'cellMarginBottom' => 120, + 'cellMarginLeft' => 120, + 'cellMarginRight' => 120, + 'borderTopSize' => 120, + 'borderBottomSize' => 120, + 'borderLeftSize' => 120, + 'borderRightSize' => 120, + 'borderInsideHSize' => 120, + 'borderInsideVSize' => 120, + ); + $PHPWord->setDefaultParagraphStyle($pStyle); + $PHPWord->addParagraphStyle('Base Style', $pBase); + $PHPWord->addParagraphStyle('New Style', $pNew); + $PHPWord->addFontStyle('New Style', $rStyle, $pStyle); + $PHPWord->addTableStyle('Table Style', $tStyle, $tStyle); + $PHPWord->addTitleStyle(1, $rStyle, $pStyle); + $doc = TestHelperDOCX::getDocument($PHPWord); + + $file = 'word/styles.xml'; + + // Normal style generated? + $path = '/w:styles/w:style[@w:styleId="Normal"]/w:name'; + $element = $doc->getElement($path, $file); + $this->assertEquals('Normal', $element->getAttribute('w:val')); + + // Parent style referenced? + $path = '/w:styles/w:style[@w:styleId="New Style"]/w:basedOn'; + $element = $doc->getElement($path, $file); + $this->assertEquals('Base Style', $element->getAttribute('w:val')); + + // Next paragraph style correct? + $path = '/w:styles/w:style[@w:styleId="New Style"]/w:next'; + $element = $doc->getElement($path, $file); + $this->assertEquals('Normal', $element->getAttribute('w:val')); + } +} diff --git a/Tests/PHPWord/Writer/Word2007Test.php b/Tests/PHPWord/Writer/Word2007Test.php new file mode 100644 index 0000000000..95abee8363 --- /dev/null +++ b/Tests/PHPWord/Writer/Word2007Test.php @@ -0,0 +1,126 @@ +assertInstanceOf( + "PHPWord_Writer_Word2007_{$part}", + $object->getWriterPart($part) + ); + $this->assertInstanceOf( + "PHPWord_Writer_Word2007", + $object->getWriterPart($part)->getParentWriter() + ); + } + } + + /** + * @covers ::save + */ + public function testSave() + { + $phpWord = new PHPWord(); + $phpWord->addFontStyle('Font', array('size' => 11)); + $phpWord->addParagraphStyle('Paragraph', array('align' => 'center')); + $section = $phpWord->createSection(); + $section->addText('Test 1', 'Font', 'Paragraph'); + $section->addTextBreak(); + $section->addText('Test 2'); + $section = $phpWord->createSection(); + $textrun = $section->createTextRun(); + $textrun->addText('Test 3'); + + $writer = new PHPWord_Writer_Word2007($phpWord); + $file = \join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, '_files', 'temp.docx') + ); + $writer->save($file); + $this->assertTrue(file_exists($file)); + unlink($file); + } + + /** + * @covers ::checkContentTypes + */ + public function testCheckContentTypes() + { + $images = array( + 'mars_noext_jpg' => '1.jpg', + 'mars.jpg' => '2.jpg', + 'mario.gif' => '3.gif', + 'firefox.png' => '4.png', + 'duke_nukem.bmp' => '5.bmp', + 'angela_merkel.tif' => '6.tif', + ); + $phpWord = new PHPWord(); + $section = $phpWord->createSection(); + foreach ($images as $source => $target) { + $section->addImage(PHPWORD_TESTS_DIR_ROOT . "/_files/images/{$source}"); + } + + $doc = TestHelperDOCX::getDocument($phpWord); + $mediaPath = $doc->getPath() . "/word/media"; + + foreach ($images as $source => $target) { + $this->assertFileEquals( + PHPWORD_TESTS_DIR_ROOT . "/_files/images/{$source}", + $mediaPath . "/section_image{$target}" + ); + } + } + + /** + * @covers ::setUseDiskCaching + * @covers ::getUseDiskCaching + */ + public function testSetGetUseDiskCaching() + { + $object = new PHPWord_Writer_Word2007(); + $object->setUseDiskCaching(true, PHPWORD_TESTS_DIR_ROOT); + + $this->assertTrue($object->getUseDiskCaching()); + } + + /** + * @covers ::setUseDiskCaching + * @expectedException Exception + */ + public function testSetUseDiskCachingException() + { + $dir = \join( + \DIRECTORY_SEPARATOR, + array(\PHPWORD_TESTS_DIR_ROOT, 'foo') + ); + + $object = new PHPWord_Writer_Word2007(); + $object->setUseDiskCaching(true, $dir); + } +} diff --git a/Tests/PHPWordTest.php b/Tests/PHPWordTest.php new file mode 100644 index 0000000000..15106af6bb --- /dev/null +++ b/Tests/PHPWordTest.php @@ -0,0 +1,186 @@ +assertEquals( + new PHPWord_DocumentProperties(), + $object->getProperties() + ); + $this->assertEquals( + PHPWord::DEFAULT_FONT_NAME, + $object->getDefaultFontName() + ); + $this->assertEquals( + PHPWord::DEFAULT_FONT_SIZE, + $object->getDefaultFontSize() + ); + } + + /** + * @covers PHPWord::setProperties + * @covers PHPWord::getProperties + */ + public function testSetGetProperties() + { + $object = new PHPWord(); + $creator = 'PHPWord'; + $properties = $object->getProperties(); + $properties->setCreator($creator); + $object->setProperties($properties); + $this->assertEquals($creator, $object->getProperties()->getCreator()); + } + + /** + * @covers PHPWord::createSection + * @covers PHPWord::getSections + */ + public function testCreateGetSections() + { + $object = new PHPWord(); + $this->assertEquals(new PHPWord_Section(1), $object->createSection()); + $object->createSection(); + $this->assertEquals(2, count($object->getSections())); + } + + /** + * @covers PHPWord::setDefaultFontName + * @covers PHPWord::getDefaultFontName + */ + public function testSetGetDefaultFontName() + { + $object = new PHPWord(); + $fontName = 'Times New Roman'; + $this->assertEquals( + PHPWord::DEFAULT_FONT_NAME, + $object->getDefaultFontName() + ); + $object->setDefaultFontName($fontName); + $this->assertEquals($fontName, $object->getDefaultFontName()); + } + + /** + * @covers PHPWord::setDefaultFontSize + * @covers PHPWord::getDefaultFontSize + */ + public function testSetGetDefaultFontSize() + { + $object = new PHPWord(); + $fontSize = 16; + $this->assertEquals( + PHPWord::DEFAULT_FONT_SIZE, + $object->getDefaultFontSize() + ); + $object->setDefaultFontSize($fontSize); + $this->assertEquals($fontSize, $object->getDefaultFontSize()); + } + + /** + * @covers PHPWord::setDefaultParagraphStyle + * @covers PHPWord::loadTemplate + */ + public function testSetDefaultParagraphStyle() + { + $object = new PHPWord(); + $object->setDefaultParagraphStyle(array()); + $this->assertInstanceOf( + 'PHPWord_Style_Paragraph', + PHPWord_Style::getStyle('Normal') + ); + } + + /** + * @covers PHPWord::addParagraphStyle + * @covers PHPWord::addFontStyle + * @covers PHPWord::addTableStyle + * @covers PHPWord::addLinkStyle + */ + public function testAddStyles() + { + $object = new PHPWord(); + $styles = array('Paragraph' => 'Paragraph', 'Font' => 'Font', + 'Table' => 'TableFull', 'Link' => 'Font'); + foreach ($styles as $key => $value) { + $method = "add{$key}Style"; + $styleId = "{$key} Style"; + $styleType = "PHPWord_Style_{$value}"; + $object->$method($styleId, array()); + $this->assertInstanceOf( + $styleType, + PHPWord_Style::getStyle($styleId) + ); + } + + } + + /** + * @covers PHPWord::addTitleStyle + */ + public function testAddTitleStyle() + { + $object = new PHPWord(); + $titleLevel = 1; + $titleName = "Heading_{$titleLevel}"; + $object->addTitleStyle($titleLevel, array()); + $this->assertInstanceOf( + 'PHPWord_Style_Font', + PHPWord_Style::getStyle($titleName) + ); + } + + /** + * @covers PHPWord::loadTemplate + */ + public function testLoadTemplate() + { + $file = join( + DIRECTORY_SEPARATOR, + array(PHPWORD_TESTS_DIR_ROOT, '_files', 'templates', 'blank.docx') + ); + $object = new PHPWord(); + $this->assertInstanceOf( + 'PHPWord_Template', + $object->loadTemplate($file) + ); + } + + /** + * @covers PHPWord::loadTemplate + * @expectedException PHPWord_Exception + */ + public function testLoadTemplateException() + { + $file = join( + DIRECTORY_SEPARATOR, + array(PHPWORD_TESTS_DIR_ROOT, '_files', 'templates', 'blanks.docx') + ); + $object = new PHPWord(); + $object->loadTemplate($file); + } +} diff --git a/Tests/_files/documents/reader.docx b/Tests/_files/documents/reader.docx new file mode 100644 index 0000000000..e2ceeb646e Binary files /dev/null and b/Tests/_files/documents/reader.docx differ diff --git a/Tests/_files/documents/reader.docx.zip b/Tests/_files/documents/reader.docx.zip new file mode 100644 index 0000000000..e2ceeb646e Binary files /dev/null and b/Tests/_files/documents/reader.docx.zip differ diff --git a/samples/old/_sheet.xls b/Tests/_files/documents/sheet.xls similarity index 100% rename from samples/old/_sheet.xls rename to Tests/_files/documents/sheet.xls diff --git a/Tests/_files/documents/without_table_macros.docx b/Tests/_files/documents/without_table_macros.docx new file mode 100644 index 0000000000..e4e9767fc1 Binary files /dev/null and b/Tests/_files/documents/without_table_macros.docx differ diff --git a/Tests/_files/images/PHPWord.png b/Tests/_files/images/PHPWord.png new file mode 100644 index 0000000000..9b7f4930f4 Binary files /dev/null and b/Tests/_files/images/PHPWord.png differ diff --git a/Tests/_files/images/alexz-johnson.pcx b/Tests/_files/images/alexz-johnson.pcx new file mode 100644 index 0000000000..cffae373be Binary files /dev/null and b/Tests/_files/images/alexz-johnson.pcx differ diff --git a/Tests/_files/images/angela_merkel.tif b/Tests/_files/images/angela_merkel.tif new file mode 100644 index 0000000000..236dedd152 Binary files /dev/null and b/Tests/_files/images/angela_merkel.tif differ diff --git a/Tests/_files/images/duke_nukem.bmp b/Tests/_files/images/duke_nukem.bmp new file mode 100644 index 0000000000..b78975d06c Binary files /dev/null and b/Tests/_files/images/duke_nukem.bmp differ diff --git a/Tests/_files/images/firefox.png b/Tests/_files/images/firefox.png new file mode 100644 index 0000000000..588afbfa6b Binary files /dev/null and b/Tests/_files/images/firefox.png differ diff --git a/Tests/_files/images/mario.gif b/Tests/_files/images/mario.gif new file mode 100644 index 0000000000..243f5b2532 Binary files /dev/null and b/Tests/_files/images/mario.gif differ diff --git a/samples/old/_mars.jpg b/Tests/_files/images/mars_noext_jpg similarity index 100% rename from samples/old/_mars.jpg rename to Tests/_files/images/mars_noext_jpg diff --git a/Tests/_files/templates/blank.docx b/Tests/_files/templates/blank.docx new file mode 100644 index 0000000000..071b7f350d Binary files /dev/null and b/Tests/_files/templates/blank.docx differ diff --git a/Tests/_files/templates/clone-row.docx b/Tests/_files/templates/clone-row.docx new file mode 100644 index 0000000000..eb944367f0 Binary files /dev/null and b/Tests/_files/templates/clone-row.docx differ diff --git a/Tests/_files/templates/corrupted_main_document_part.docx b/Tests/_files/templates/corrupted_main_document_part.docx new file mode 100644 index 0000000000..69712525a4 Binary files /dev/null and b/Tests/_files/templates/corrupted_main_document_part.docx differ diff --git a/Tests/_files/templates/with_table_macros.docx b/Tests/_files/templates/with_table_macros.docx new file mode 100644 index 0000000000..cd5ed6cedb Binary files /dev/null and b/Tests/_files/templates/with_table_macros.docx differ diff --git a/Tests/_files/xsl/passthrough.xsl b/Tests/_files/xsl/passthrough.xsl new file mode 100644 index 0000000000..4ab21dd745 --- /dev/null +++ b/Tests/_files/xsl/passthrough.xsl @@ -0,0 +1,11 @@ + + + + + + + + + + \ No newline at end of file diff --git a/Tests/_files/xsl/remove_tables_by_needle.xsl b/Tests/_files/xsl/remove_tables_by_needle.xsl new file mode 100644 index 0000000000..1a7b13693d --- /dev/null +++ b/Tests/_files/xsl/remove_tables_by_needle.xsl @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/Tests/_inc/TestHelperDOCX.php b/Tests/_inc/TestHelperDOCX.php index 32f1af08bc..dec1f0776f 100644 --- a/Tests/_inc/TestHelperDOCX.php +++ b/Tests/_inc/TestHelperDOCX.php @@ -2,43 +2,43 @@ namespace PHPWord\Tests; use PHPWord; -use DOMDocument; class TestHelperDOCX { + /** @var string $file */ static protected $file; /** * @param \PHPWord $PHPWord - * @return \PHPWord\Tests\Xml_Document + * @return \PHPWord\Tests\XmlDocument */ - public static function getDocument(PHPWord $PHPWord) + public static function getDocument(PHPWord $PHPWord, $writer = 'Word2007') { self::$file = tempnam(sys_get_temp_dir(), 'PHPWord'); - if(!is_dir(sys_get_temp_dir().'/PHPWord_Unit_Test/')){ - mkdir(sys_get_temp_dir().'/PHPWord_Unit_Test/'); + if (!is_dir(sys_get_temp_dir() . '/PHPWord_Unit_Test/')) { + mkdir(sys_get_temp_dir() . '/PHPWord_Unit_Test/'); } - $objWriter = \PHPWord_IOFactory::createWriter($PHPWord, 'Word2007'); + $objWriter = \PHPWord_IOFactory::createWriter($PHPWord, $writer); $objWriter->save(self::$file); $zip = new \ZipArchive; $res = $zip->open(self::$file); if ($res === true) { - $zip->extractTo(sys_get_temp_dir().'/PHPWord_Unit_Test/'); + $zip->extractTo(sys_get_temp_dir() . '/PHPWord_Unit_Test/'); $zip->close(); } - return new Xml_Document(sys_get_temp_dir().'/PHPWord_Unit_Test/'); + return new XmlDocument(sys_get_temp_dir() . '/PHPWord_Unit_Test/'); } public static function clear() { - if(file_exists(self::$file)){ - unlink(self::$file); + if (file_exists(self::$file)) { + unlink(self::$file); } - if(is_dir(sys_get_temp_dir().'/PHPWord_Unit_Test/')){ - self::deleteDir(sys_get_temp_dir().'/PHPWord_Unit_Test/'); + if (is_dir(sys_get_temp_dir() . '/PHPWord_Unit_Test/')) { + self::deleteDir(sys_get_temp_dir() . '/PHPWord_Unit_Test/'); } } @@ -50,75 +50,21 @@ public static function deleteDir($dir) foreach (scandir($dir) as $file) { if ($file === '.' || $file === '..') { continue; - } else if (is_file($dir . "/" . $file)) { + } elseif (is_file($dir . "/" . $file)) { unlink($dir . "/" . $file); - } else if (is_dir($dir . "/" . $file)) { + } elseif (is_dir($dir . "/" . $file)) { self::deleteDir($dir . "/" . $file); } } rmdir($dir); } -} - -class Xml_Document -{ - /** @var string $path */ - private $path; - - /** @var \DOMDocument $dom */ - private $dom; - - /** @var \DOMXpath $xpath */ - private $xpath; - - /** @var string $file */ - private $file; /** - * @param string $path + * @return string */ - public function __construct($path) + public static function getFile() { - $this->path = realpath($path); + return self::$file; } - - /** - * @param string $file - * @return \DOMDocument - */ - public function getFileDom($file = 'word/document.xml') - { - if (null !== $this->dom && $file === $this->file) { - return $this->dom; - } - - $this->xpath = null; - $this->file = $file; - - $file = $this->path . '/' . $file; - $this->dom = new DOMDocument(); - $this->dom->load($file); - return $this->dom; - } - - /** - * @param string $path - * @param string $file - * @return \DOMElement - */ - public function getElement($path, $file = 'word/document.xml') - { - if ($this->dom === null || $file !== $this->file) { - $this->getFileDom($file); - } - - if (null === $this->xpath) { - $this->xpath = new \DOMXpath($this->dom); - - } - - $elements = $this->xpath->query($path); - return $elements->item(0); - } -} \ No newline at end of file +} diff --git a/Tests/_inc/XmlDocument.php b/Tests/_inc/XmlDocument.php new file mode 100644 index 0000000000..4d3d00347d --- /dev/null +++ b/Tests/_inc/XmlDocument.php @@ -0,0 +1,115 @@ +path = realpath($path); + } + + /** + * @param string $file + * @return \DOMDocument + */ + public function getFileDom($file = 'word/document.xml') + { + if (null !== $this->dom && $file === $this->file) { + return $this->dom; + } + + $this->xpath = null; + $this->file = $file; + + $file = $this->path . '/' . $file; + $this->dom = new DOMDocument(); + $this->dom->load($file); + return $this->dom; + } + + /** + * @param string $path + * @param string $file + * @return \DOMNodeList + */ + public function getNodeList($path, $file = 'word/document.xml') + { + if ($this->dom === null || $file !== $this->file) { + $this->getFileDom($file); + } + + if (null === $this->xpath) { + $this->xpath = new \DOMXpath($this->dom); + + } + + return $this->xpath->query($path); + } + + /** + * @param string $path + * @param string $file + * @return \DOMElement + */ + public function getElement($path, $file = 'word/document.xml') + { + $elements = $this->getNodeList($path, $file); + + return $elements->item(0); + } + + /** + * @return string + */ + public function getFile() + { + return $this->file; + } + + /** + * @return string + */ + public function getPath() + { + return $this->path; + } + + /** + * @param string $path + * @param string $attribute + * @param string $file + * @return string + */ + public function getElementAttribute($path, $attribute, $file = 'word/document.xml') + { + return $this->getElement($path, $file)->getAttribute($attribute); + } + + /** + * @param string $path + * @param string $file + * @return string + */ + public function elementExists($path, $file = 'word/document.xml') + { + $nodeList = $this->getNodeList($path, $file); + return !($nodeList->length == 0); + } +} diff --git a/Tests/bootstrap.php b/Tests/bootstrap.php index 554dc38f22..1066a0d42c 100755 --- a/Tests/bootstrap.php +++ b/Tests/bootstrap.php @@ -3,8 +3,8 @@ date_default_timezone_set('UTC'); // Constantes -if(!defined('PHPWORD_TESTS_DIR_ROOT')){ - define('PHPWORD_TESTS_DIR_ROOT', __DIR__); +if (!defined('PHPWORD_TESTS_DIR_ROOT')) { + define('PHPWORD_TESTS_DIR_ROOT', __DIR__); } // Includes @@ -12,3 +12,4 @@ PHPWord_Autoloader::Register(); require_once __DIR__ . '/_inc/TestHelperDOCX.php'; +require_once __DIR__ . '/_inc/XmlDocument.php'; diff --git a/changelog.txt b/changelog.txt index 7b5375b465..d603eecd0a 100755 --- a/changelog.txt +++ b/changelog.txt @@ -22,12 +22,42 @@ * @version ##VERSION##, ##DATE## ************************************************************************************** -Changes in branch for release 0.7.1 : +Changes in branch for release 0.8.0 : - Bugfix: (gabrielbull) - Fixed bug with cell styling - Bugfix: (gabrielbull) - Fixed bug list items inside of cells +- Bugfix: (SiebelsTim) GH-51 - Adding a value that contains "&" in a template breaks it +- Bugfix: (Progi1984) GH-89 - Example in README.md is broken - Feature: (RomanSyroeshko) GH-56 GH-57 - Template : Permit to save a template generated as a file (PHPWord_Template::saveAs()) - Feature: (gabrielbull) - Word2007 : Support sections page numbering -- Feature: (gabrielbull) - Word2007 : Added support for line height +- Feature: (gabrielbull) - Word2007 : Added line height methods to mirror the line height settings in Word in the paragraph styling +- Feature: (JillElaine) GH-5 - Word2007 : Added support for page header & page footer height +- Feature: (bskrtich) GH-6 GH-66 GH-84 - General : Add ability to manage line breaks after image insertion +- Feature: (RomanSyroeshko) GH-52 GH-53 GH-85 - Template : Ability to limit number of replacements performed by setValue() method of Template class +- Feature: (ivanlanin) GH-48 GH-86 - Table row: Repeat as header row & allow row to break across pages +- Feature: (ivanlanin) GH-48 GH-86 - Table: Table width in percentage +- Feature: (ivanlanin) GH-48 GH-86 - Font: Superscript and subscript +- Feature: (ivanlanin) GH-48 GH-86 - Paragraph: Hanging paragraph +- Feature: (ivanlanin) GH-48 GH-86 - Section: Multicolumn and section break +- Feature: (RomanSyroeshko) GH-46 GH-47 GH-83 - Template : Ability to apply XSL style sheet to Template +- Feature: (ivanlanin) GH-87 - General: PHPWord_Shared_Font::pointSizeToTwips() converter +- Feature: (ivanlanin) GH-87 - Paragraph: Ability to define normal paragraph style with PHPWord::setNormalStyle() +- Feature: (ivanlanin) GH-87 - Paragraph: Ability to define parent style (basedOn) and style for following paragraph (next) +- Feature: (jeroenmoors) GH-44 GH-88 - Clone table rows on the fly when using a template document +- Feature: (deds) GH-16 - Initial addition of basic footnote support +- Feature: (ivanlanin) GH-92 - Paragraph: Ability to define paragraph pagination: widow control, keep next, keep lines, and page break before +- General: (ivanlanin) GH-93 - General: PHPWord_Style_Font refactoring +- General: (ivanlanin) GH-93 - Font: Use points instead of halfpoints internally. Conversion to halfpoints done during XML Writing. +- Bugfix: (ivanlanin) GH-94 - General: PHPWord_Shared_Drawing::centimetersToPixels() conversion +- Feature: (ivanlanin) GH-92 - Paragraph: setTabs() function +- Feature: (ivanlanin) GH-99 - General: Basic support for TextRun on ODT and RTF +- Feature: (ivanlanin) GH-104 - Reader: Basic Reader for Word2007 +- Feature: (bskrtich ) GH-109 - TextRun: Allow Text Break in Text Run +- Feature: (jhfangying) GH-111 GH-118 - General: Support for East Asian fontstyle +- Feature: (gabrielbull) GH-114 - Image: Use exif_imagetype to check image format instead of extension name +- Feature: (bskrtich ) GH-103 - General: Setting for XMLWriter Compatibility option +- Feature: (ivanlanin) GH-122 - MemoryImage: Allow remote image when allow_url_open = on +- Bugfix: (ivanlanin) GH-125 - Footnote: Corrupt DOCX reported by MS Word when sections > 1 and not every sections have footnote +- Feature: (ivanlanin) GH-18 - TextBreak: Allow font and paragraph style for text break - QA: (Progi1984) - UnitTests Changes in branch for release 0.7.0 : diff --git a/composer.json b/composer.json index 8a73f47189..962ed78ef6 100644 --- a/composer.json +++ b/composer.json @@ -21,15 +21,19 @@ ], "require": { "php": ">=5.3.0", - "ext-xml": "*" + "ext-xml": "*", + "ext-zip": "*" }, "require-dev": { - "phpunit/phpunit": "3.7.28" + "phpunit/phpunit": "3.7.*" }, "recommend": { - "ext-zip": "*", "ext-gd2": "*" }, + "suggest": { + "ext-xmlwriter": "*", + "ext-xsl": "*" + }, "autoload": { "psr-0": { "PHPWord": "Classes/" diff --git a/phpunit.xml.dist b/phpunit.xml.dist index e57799ce6e..908304adea 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -15,7 +15,7 @@ - ../Classes + ./Classes diff --git a/samples/Sample_01_SimpleText.php b/samples/Sample_01_SimpleText.php index b2d6593a75..10f129dbfa 100755 --- a/samples/Sample_01_SimpleText.php +++ b/samples/Sample_01_SimpleText.php @@ -1,51 +1,62 @@ '); -} - +define('EOL', (PHP_SAPI == 'cli') ? PHP_EOL : '
'); require_once '../Classes/PHPWord.php'; // New Word Document echo date('H:i:s') , " Create new PHPWord object" , EOL; $PHPWord = new PHPWord(); +$PHPWord->addFontStyle('rStyle', array('bold' => true, 'italic' => true, 'size' => 16)); +$PHPWord->addParagraphStyle('pStyle', array('align' => 'center', 'spaceAfter' => 100)); +$PHPWord->addTitleStyle(1, array('bold' => true), array('spaceAfter' => 240)); // New portrait section $section = $PHPWord->createSection(); -// Add text elements +// Simple text +$section->addTitle('Welcome to PHPWord', 1); $section->addText('Hello World!'); -$section->addTextBreak(2); -$section->addText('I am inline styled.', array('name'=>'Verdana', 'color'=>'006699')); +// Two text break $section->addTextBreak(2); -$PHPWord->addFontStyle('rStyle', array('bold'=>true, 'italic'=>true, 'size'=>16)); -$PHPWord->addParagraphStyle('pStyle', array('align'=>'center', 'spaceAfter'=>100)); -$section->addText('I am styled by two style definitions.', 'rStyle', 'pStyle'); -$section->addText('I have only a paragraph style definition.', null, 'pStyle'); - -// Save File -echo date('H:i:s') , " Write to Word2007 format" , EOL; -$objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'Word2007'); -$objWriter->save(str_replace('.php', '.docx', __FILE__)); - -echo date('H:i:s') , " Write to OpenDocumentText format" , EOL; -$objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'ODText'); -$objWriter->save(str_replace('.php', '.odt', __FILE__)); - -echo date('H:i:s') , " Write to RTF format" , EOL; -$objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'RTF'); -$objWriter->save(str_replace('.php', '.rtf', __FILE__)); - - -// Echo memory peak usage -echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true) / 1024 / 1024) , " MB" , EOL; +// Defined style +$section->addText('I am styled by a font style definition.', 'rStyle'); +$section->addText('I am styled by a paragraph style definition.', null, 'pStyle'); +$section->addText('I am styled by both font and paragraph style.', 'rStyle', 'pStyle'); +$section->addTextBreak(); + +// Inline font style +$fontStyle['name'] = 'Times New Roman'; +$fontStyle['size'] = 20; +$fontStyle['bold'] = true; +$fontStyle['italic'] = true; +$fontStyle['underline'] = 'dash'; +$fontStyle['strikethrough'] = true; +$fontStyle['superScript'] = true; +$fontStyle['color'] = 'FF0000'; +$fontStyle['fgColor'] = 'yellow'; +$section->addText('I am inline styled.', $fontStyle); +$section->addTextBreak(); + +// Link +$section->addLink('http://www.google.com', null, 'NLink'); +$section->addTextBreak(); + +// Image +$section->addImage('resources/_earth.jpg', array('width'=>18, 'height'=>18)); + +// Save file +$name = basename(__FILE__, '.php'); +$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); +foreach ($writers as $writer => $extension) { + echo date('H:i:s'), " Write to {$writer} format", EOL; + $objWriter = PHPWord_IOFactory::createWriter($PHPWord, $writer); + $objWriter->save("{$name}.{$extension}"); + rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +} -// Echo done -echo date('H:i:s') , " Done writing file" , EOL; +// Done +echo date('H:i:s'), " Done writing file(s)", EOL; +echo date('H:i:s'), " Peak memory usage: ", (memory_get_peak_usage(true) / 1024 / 1024), " MB", EOL; diff --git a/samples/Sample_02_TabStops.php b/samples/Sample_02_TabStops.php index 177e8598f1..e9e2d84bcb 100755 --- a/samples/Sample_02_TabStops.php +++ b/samples/Sample_02_TabStops.php @@ -1,14 +1,7 @@ '); -} - +define('EOL', (PHP_SAPI == 'cli') ? PHP_EOL : '
'); require_once '../Classes/PHPWord.php'; // New Word Document @@ -42,22 +35,16 @@ $section->addText("Left Aligned\tRight Aligned", NULL, 'rightTab'); $section->addText("\tCenter Aligned", NULL, 'centerTab'); -// Save File -echo date('H:i:s') , ' Write to Word2007 format' , EOL; -$objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'Word2007'); -$objWriter->save(str_replace('.php', '.docx', __FILE__)); - -echo date('H:i:s') , ' Write to OpenDocumentText format' , EOL; -$objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'ODText'); -$objWriter->save(str_replace('.php', '.odt', __FILE__)); - -echo date('H:i:s') , ' Write to RTF format' , EOL; -$objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'RTF'); -$objWriter->save(str_replace('.php', '.rtf', __FILE__)); - - -// Echo memory peak usage -echo date('H:i:s') , ' Peak memory usage: ' , (memory_get_peak_usage(true) / 1024 / 1024) , ' MB' , EOL; +// Save file +$name = basename(__FILE__, '.php'); +$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); +foreach ($writers as $writer => $extension) { + echo date('H:i:s'), " Write to {$writer} format", EOL; + $objWriter = PHPWord_IOFactory::createWriter($PHPWord, $writer); + $objWriter->save("{$name}.{$extension}"); + rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +} -// Echo done -echo date('H:i:s') , ' Done writing file' , EOL; \ No newline at end of file +// Done +echo date('H:i:s'), " Done writing file(s)", EOL; +echo date('H:i:s'), " Peak memory usage: ", (memory_get_peak_usage(true) / 1024 / 1024), " MB", EOL; diff --git a/samples/Sample_03_Sections.php b/samples/Sample_03_Sections.php new file mode 100755 index 0000000000..1e49629e9c --- /dev/null +++ b/samples/Sample_03_Sections.php @@ -0,0 +1,43 @@ +'); +require_once '../Classes/PHPWord.php'; + +// New Word Document +echo date('H:i:s') , ' Create new PHPWord object' , EOL; +$PHPWord = new PHPWord(); + +// New portrait section +$section = $PHPWord->createSection(array('borderColor' => '00FF00', 'borderSize' => 12)); +$section->addText('I am placed on a default section.'); + +// New landscape section +$section = $PHPWord->createSection(array('orientation' => 'landscape')); +$section->addText('I am placed on a landscape section. Every page starting from this section will be landscape style.'); +$section->addPageBreak(); +$section->addPageBreak(); + +// New portrait section +$section = $PHPWord->createSection(array('marginLeft' => 600, 'marginRight' => 600, 'marginTop' => 600, 'marginBottom' => 600)); +$section->addText('This section uses other margins.'); + +// New portrait section with Header & Footer +$section = $PHPWord->createSection(array('marginLeft' => 200, 'marginRight' => 200, 'marginTop' => 200, 'marginBottom' => 200, 'headerHeight' => 50, 'footerHeight' => 50,)); +$section->addText('This section and we play with header/footer height.'); +$section->createHeader()->addText('Header'); +$section->createFooter()->addText('Footer'); + +// Save file +$name = basename(__FILE__, '.php'); +$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); +foreach ($writers as $writer => $extension) { + echo date('H:i:s'), " Write to {$writer} format", EOL; + $objWriter = PHPWord_IOFactory::createWriter($PHPWord, $writer); + $objWriter->save("{$name}.{$extension}"); + rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +} + +// Done +echo date('H:i:s'), " Done writing file(s)", EOL; +echo date('H:i:s'), " Peak memory usage: ", (memory_get_peak_usage(true) / 1024 / 1024), " MB", EOL; diff --git a/samples/Sample_04_Textrun.php b/samples/Sample_04_Textrun.php new file mode 100644 index 0000000000..b30db7a56f --- /dev/null +++ b/samples/Sample_04_Textrun.php @@ -0,0 +1,50 @@ +'); +require_once '../Classes/PHPWord.php'; + +// New Word Document +echo date('H:i:s') , ' Create new PHPWord object' , EOL; +$PHPWord = new PHPWord(); + + +// Ads styles +$PHPWord->addParagraphStyle('pStyle', array('spacing'=>100)); +$PHPWord->addFontStyle('BoldText', array('bold'=>true)); +$PHPWord->addFontStyle('ColoredText', array('color'=>'FF8080')); +$PHPWord->addLinkStyle('NLink', array('color'=>'0000FF', 'underline'=>PHPWord_Style_Font::UNDERLINE_SINGLE)); + +// New portrait section +$section = $PHPWord->createSection(); + +// Add text run +$textrun = $section->createTextRun('pStyle'); + +$textrun->addText('Each textrun can contain native text, link elements or an image.'); +$textrun->addText(' No break is placed after adding an element.', 'BoldText'); +$textrun->addText(' Both '); +$textrun->addText('superscript', array('superScript' => true)); +$textrun->addText(' and '); +$textrun->addText('subscript', array('subScript' => true)); +$textrun->addText(' are also available.'); +$textrun->addText(' All elements are placed inside a paragraph with the optionally given p-Style.', 'ColoredText'); +$textrun->addText(' Sample Link: '); +$textrun->addLink('http://www.google.com', null, 'NLink'); +$textrun->addText(' Sample Image: '); +$textrun->addImage('resources/_earth.jpg', array('width'=>18, 'height'=>18)); +$textrun->addText(' Here is some more text. '); + +// Save file +$name = basename(__FILE__, '.php'); +$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); +foreach ($writers as $writer => $extension) { + echo date('H:i:s'), " Write to {$writer} format", EOL; + $objWriter = PHPWord_IOFactory::createWriter($PHPWord, $writer); + $objWriter->save("{$name}.{$extension}"); + rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +} + +// Done +echo date('H:i:s'), " Done writing file(s)", EOL; +echo date('H:i:s'), " Peak memory usage: ", (memory_get_peak_usage(true) / 1024 / 1024), " MB", EOL; diff --git a/samples/Sample_05_Multicolumn.php b/samples/Sample_05_Multicolumn.php new file mode 100644 index 0000000000..3877defeff --- /dev/null +++ b/samples/Sample_05_Multicolumn.php @@ -0,0 +1,53 @@ +'); +require_once '../Classes/PHPWord.php'; + +// New Word Document +echo date('H:i:s') , " Create new PHPWord object" , EOL; +$PHPWord = new PHPWord(); +$filler = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. ' . + 'Nulla fermentum, tortor id adipiscing adipiscing, tortor turpis commodo. ' . + 'Donec vulputate iaculis metus, vel luctus dolor hendrerit ac. ' . + 'Suspendisse congue congue leo sed pellentesque.'; + +// Normal +$section = $PHPWord->createSection(); +$section->addText('Normal paragraph. ' . $filler); + +// Two columns +$section = $PHPWord->createSection(array( + 'colsNum' => 2, + 'colsSpace' => 1440, + 'breakType' => 'continuous')); +$section->addText('Three columns, one inch (1440 twips) spacing. ' . $filler); + +// Normal +$section = $PHPWord->createSection(array('breakType' => 'continuous')); +$section->addText('Normal paragraph again. ' . $filler); + +// Three columns +$section = $PHPWord->createSection(array( + 'colsNum' => 3, + 'colsSpace' => 720, + 'breakType' => 'continuous')); +$section->addText('Three columns, half inch (720 twips) spacing. ' . $filler); + +// Normal +$section = $PHPWord->createSection(array('breakType' => 'continuous')); +$section->addText('Normal paragraph again.'); + +// Save file +$name = basename(__FILE__, '.php'); +$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); +foreach ($writers as $writer => $extension) { + echo date('H:i:s'), " Write to {$writer} format", EOL; + $objWriter = PHPWord_IOFactory::createWriter($PHPWord, $writer); + $objWriter->save("{$name}.{$extension}"); + rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +} + +// Done +echo date('H:i:s'), " Done writing file(s)", EOL; +echo date('H:i:s'), " Peak memory usage: ", (memory_get_peak_usage(true) / 1024 / 1024), " MB", EOL; diff --git a/samples/Sample_06_Footnote.php b/samples/Sample_06_Footnote.php new file mode 100755 index 0000000000..daaa6b4636 --- /dev/null +++ b/samples/Sample_06_Footnote.php @@ -0,0 +1,51 @@ +'); +require_once '../Classes/PHPWord.php'; + +// New Word Document +echo date('H:i:s') , " Create new PHPWord object" , EOL; +$PHPWord = new PHPWord(); + +// New portrait section +$section = $PHPWord->createSection(); + +// Add style definitions +$PHPWord->addParagraphStyle('pStyle', array('spacing'=>100)); +$PHPWord->addFontStyle('BoldText', array('bold'=>true)); +$PHPWord->addFontStyle('ColoredText', array('color'=>'FF8080')); +$PHPWord->addLinkStyle('NLink', array('color'=>'0000FF', 'underline'=>PHPWord_Style_Font::UNDERLINE_SINGLE)); + +// Add text elements +$textrun = $section->createTextRun('pStyle'); +$textrun->addText('This is some lead text in a paragraph with a following footnote. ','pStyle'); + +$footnote = $textrun->createFootnote(); +$footnote->addText('Just like a textrun a footnote can contain native text and link elements.'); +$footnote->addText(' No break is placed after adding an element.', 'BoldText'); +$footnote->addText(' All elements are placed inside a paragraph.', 'ColoredText'); +$footnote->addText(' The best search engine: '); +$footnote->addLink('http://www.google.com', null, 'NLink'); +$footnote->addText('. Also not bad: '); +$footnote->addLink('http://www.bing.com', null, 'NLink'); + +$textrun->addText('The trailing text in the paragraph.'); + +$section->addText('You can also create the footnote directly from the section making it wrap in a paragraph like the footnote below this paragraph. But is is best used from within a textrun.'); +$footnote = $section->createFootnote(); +$footnote->addText('The reference for this is wrapped in its own line'); + +// Save file +$name = basename(__FILE__, '.php'); +$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); +foreach ($writers as $writer => $extension) { + echo date('H:i:s'), " Write to {$writer} format", EOL; + $objWriter = PHPWord_IOFactory::createWriter($PHPWord, $writer); + $objWriter->save("{$name}.{$extension}"); + rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +} + +// Done +echo date('H:i:s'), " Done writing file(s)", EOL; +echo date('H:i:s'), " Peak memory usage: ", (memory_get_peak_usage(true) / 1024 / 1024), " MB", EOL; diff --git a/samples/Sample_07_TemplateCloneRow.php b/samples/Sample_07_TemplateCloneRow.php new file mode 100755 index 0000000000..f797b986e5 --- /dev/null +++ b/samples/Sample_07_TemplateCloneRow.php @@ -0,0 +1,66 @@ +'); +require_once '../Classes/PHPWord.php'; + +// New Word document +echo date('H:i:s') , " Create new PHPWord object" , EOL; +$PHPWord = new PHPWord(); + +$document = $PHPWord->loadTemplate('resources/Sample_07_TemplateCloneRow.docx'); + +// Simple table +$document->cloneRow('rowValue', 10); + +$document->setValue('rowValue#1', 'Sun'); +$document->setValue('rowValue#2', 'Mercury'); +$document->setValue('rowValue#3', 'Venus'); +$document->setValue('rowValue#4', 'Earth'); +$document->setValue('rowValue#5', 'Mars'); +$document->setValue('rowValue#6', 'Jupiter'); +$document->setValue('rowValue#7', 'Saturn'); +$document->setValue('rowValue#8', 'Uranus'); +$document->setValue('rowValue#9', 'Neptun'); +$document->setValue('rowValue#10', 'Pluto'); + +$document->setValue('rowNumber#1', '1'); +$document->setValue('rowNumber#2', '2'); +$document->setValue('rowNumber#3', '3'); +$document->setValue('rowNumber#4', '4'); +$document->setValue('rowNumber#5', '5'); +$document->setValue('rowNumber#6', '6'); +$document->setValue('rowNumber#7', '7'); +$document->setValue('rowNumber#8', '8'); +$document->setValue('rowNumber#9', '9'); +$document->setValue('rowNumber#10', '10'); + +$document->setValue('weekday', date('l')); +$document->setValue('time', date('H:i')); + +// Table with a spanned cell +$document->cloneRow('userId', 3); + +$document->setValue('userId#1', '1'); +$document->setValue('userFirstName#1', 'James'); +$document->setValue('userName#1', 'Taylor'); +$document->setValue('userPhone#1', '+1 428 889 773'); + +$document->setValue('userId#2', '2'); +$document->setValue('userFirstName#2', 'Robert'); +$document->setValue('userName#2', 'Bell'); +$document->setValue('userPhone#2', '+1 428 889 774'); + +$document->setValue('userId#3', '3'); +$document->setValue('userFirstName#3', 'Michael'); +$document->setValue('userName#3', 'Ray'); +$document->setValue('userPhone#3', '+1 428 889 775'); + +$name = 'Sample_07_TemplateCloneRow_result.docx'; +echo date('H:i:s'), " Write to Word2007 format", EOL; +$document->saveAs($name); +rename($name, "results/{$name}"); + +// Done +echo date('H:i:s'), " Done writing file(s)", EOL; +echo date('H:i:s'), " Peak memory usage: ", (memory_get_peak_usage(true) / 1024 / 1024), " MB", EOL; diff --git a/samples/Sample_08_ParagraphPagination.php b/samples/Sample_08_ParagraphPagination.php new file mode 100644 index 0000000000..edd1992c43 --- /dev/null +++ b/samples/Sample_08_ParagraphPagination.php @@ -0,0 +1,63 @@ +'); +require_once '../Classes/PHPWord.php'; + +// New Word document +echo date('H:i:s') , " Create new PHPWord object" , EOL; +$PHPWord = new PHPWord(); +$PHPWord->setDefaultParagraphStyle(array( + 'align' => 'both', + 'spaceAfter' => PHPWord_Shared_Font::pointSizeToTwips(12), + 'spacing' => 120, +)); + +// Sample +$section = $PHPWord->createSection(); + +$section->addText('Below are the samples on how to control your paragraph ' . + 'pagination. See "Line and Page Break" tab on paragraph properties ' . + 'window to see the attribute set by these controls.', + array('bold' => true), null); + +$section->addText('Paragraph with widowControl = false (default: true). ' . + 'A "widow" is the last line of a paragraph printed by itself at the top ' . + 'of a page. An "orphan" is the first line of a paragraph printed by ' . + 'itself at the bottom of a page. Set this option to "false" if you want ' . + 'to disable this automatic control.', + null, array('widowControl' => false)); + +$section->addText('Paragraph with keepNext = true (default: false). ' . + '"Keep with next" is used to prevent Word from inserting automatic page ' . + 'breaks between paragraphs. Set this option to "true" if you do not want ' . + 'your paragraph to be separated with the next paragraph.', + null, array('keepNext' => true)); + +$section->addText('Paragraph with keepLines = true (default: false). ' . + '"Keep lines together" will prevent Word from inserting an automatic page ' . + 'break within a paragraph. Set this option to "true" if you do not want ' . + 'all lines of your paragraph to be in the same page.', + null, array('keepLines' => true)); + +$section->addText('Keep scrolling. More below.'); + +$section->addText('Paragraph with pageBreakBefore = true (default: false). ' . + 'Different with all other control above, "page break before" separates ' . + 'your paragraph into the next page. This option is most useful for ' . + 'heading styles.', + null, array('pageBreakBefore' => true)); + +// Save file +$name = basename(__FILE__, '.php'); +$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); +foreach ($writers as $writer => $extension) { + echo date('H:i:s'), " Write to {$writer} format", EOL; + $objWriter = PHPWord_IOFactory::createWriter($PHPWord, $writer); + $objWriter->save("{$name}.{$extension}"); + rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +} + +// Done +echo date('H:i:s'), " Done writing file(s)", EOL; +echo date('H:i:s'), " Peak memory usage: ", (memory_get_peak_usage(true) / 1024 / 1024), " MB", EOL; diff --git a/samples/Sample_09_Tables.php b/samples/Sample_09_Tables.php new file mode 100644 index 0000000000..96e411a020 --- /dev/null +++ b/samples/Sample_09_Tables.php @@ -0,0 +1,91 @@ +'); +require_once '../Classes/PHPWord.php'; + +// New Word Document +echo date('H:i:s') , ' Create new PHPWord object' , EOL; +$PHPWord = new PHPWord(); +$section = $PHPWord->createSection(); +$header = array('size' => 16, 'bold' => true); + +// 1. Basic table + +$rows = 10; +$cols = 5; +$section->addText("Basic table", $header); + +$table = $section->addTable(); +for($r = 1; $r <= 8; $r++) { + $table->addRow(); + for($c = 1; $c <= 5; $c++) { + $table->addCell(1750)->addText("Row $r, Cell $c"); + } +} + +// 2. Advanced table + +$section->addTextBreak(1); +$section->addText("Fancy table", $header); + +$styleTable = array('borderSize' => 6, 'borderColor' => '006699', 'cellMargin' => 80); +$styleFirstRow = array('borderBottomSize' => 18, 'borderBottomColor' => '0000FF', 'bgColor' => '66BBFF'); +$styleCell = array('valign' => 'center'); +$styleCellBTLR = array('valign' => 'center', 'textDirection' => PHPWord_Style_Cell::TEXT_DIR_BTLR); +$fontStyle = array('bold' => true, 'align' => 'center'); +$PHPWord->addTableStyle('Fancy Table', $styleTable, $styleFirstRow); +$table = $section->addTable('Fancy Table'); +$table->addRow(900); +$table->addCell(2000, $styleCell)->addText('Row 1', $fontStyle); +$table->addCell(2000, $styleCell)->addText('Row 2', $fontStyle); +$table->addCell(2000, $styleCell)->addText('Row 3', $fontStyle); +$table->addCell(2000, $styleCell)->addText('Row 4', $fontStyle); +$table->addCell(500, $styleCellBTLR)->addText('Row 5', $fontStyle); +for($i = 1; $i <= 8; $i++) { + $table->addRow(); + $table->addCell(2000)->addText("Cell $i"); + $table->addCell(2000)->addText("Cell $i"); + $table->addCell(2000)->addText("Cell $i"); + $table->addCell(2000)->addText("Cell $i"); + $text = ($i % 2 == 0) ? 'X' : ''; + $table->addCell(500)->addText($text); +} + +// 3. colspan (gridSpan) and rowspan (vMerge) + +$section->addTextBreak(1); +$section->addText("Table with colspan and rowspan", $header); + +$styleTable = array('borderSize' => 6, 'borderColor' => '999999'); +$cellRowSpan = array('vMerge' => 'restart', 'valign' => 'center'); +$cellRowContinue = array('vMerge' => 'continue'); +$cellColSpan = array('gridSpan' => 2, 'valign' => 'center'); +$cellHCentered = array('align' => 'center'); +$cellVCentered = array('valign' => 'center'); + +$PHPWord->addTableStyle('Colspan Rowspan', $styleTable); +$table = $section->addTable('Colspan Rowspan'); +$table->addRow(); +$table->addCell(2000, $cellRowSpan)->addText('A', null, $cellHCentered); +$table->addCell(4000, $cellColSpan)->addText('B', null, $cellHCentered); +$table->addCell(2000, $cellRowSpan)->addText('E', null, $cellHCentered); +$table->addRow(); +$table->addCell(null, $cellRowContinue); +$table->addCell(2000, $cellVCentered)->addText('C', null, $cellHCentered); +$table->addCell(2000, $cellVCentered)->addText('D', null, $cellHCentered); +$table->addCell(null, $cellRowContinue); + +// Save file +$name = basename(__FILE__, '.php'); +$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); +foreach ($writers as $writer => $extension) { + echo date('H:i:s'), " Write to {$writer} format", EOL; + $objWriter = PHPWord_IOFactory::createWriter($PHPWord, $writer); + $objWriter->save("{$name}.{$extension}"); + rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +} + +// Done +echo date('H:i:s'), " Done writing file(s)", EOL; +echo date('H:i:s'), " Peak memory usage: ", (memory_get_peak_usage(true) / 1024 / 1024), " MB", EOL; diff --git a/samples/Sample_10_EastAsianFontStyle.php b/samples/Sample_10_EastAsianFontStyle.php new file mode 100644 index 0000000000..8be721091c --- /dev/null +++ b/samples/Sample_10_EastAsianFontStyle.php @@ -0,0 +1,27 @@ +'); +require_once '../Classes/PHPWord.php'; + +// New Word Document +echo date('H:i:s') , ' Create new PHPWord object' , EOL; +$PHPWord = new PHPWord(); +$section = $PHPWord->createSection(); +$header = array('size' => 16, 'bold' => true); +//1.Use EastAisa FontStyle +$section->addText('中文楷体样式测试',array('name' => '楷体', 'size' => 16, 'color' => '1B2232')); + +// Save file +$name = basename(__FILE__, '.php'); +$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); +foreach ($writers as $writer => $extension) { + echo date('H:i:s'), " Write to {$writer} format", EOL; + $objWriter = PHPWord_IOFactory::createWriter($PHPWord, $writer); + $objWriter->save("{$name}.{$extension}"); + rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +} + +// Done +echo date('H:i:s'), " Done writing file(s)", EOL; +echo date('H:i:s'), " Peak memory usage: ", (memory_get_peak_usage(true) / 1024 / 1024), " MB", EOL; diff --git a/samples/Sample_11_ReadWord2007.php b/samples/Sample_11_ReadWord2007.php new file mode 100644 index 0000000000..d96e92644c --- /dev/null +++ b/samples/Sample_11_ReadWord2007.php @@ -0,0 +1,24 @@ +'); +require_once '../Classes/PHPWord.php'; + +// Read contents +$name = basename(__FILE__, '.php'); +$source = "resources/{$name}.docx"; +echo date('H:i:s'), " Reading contents from `{$source}`", EOL; +$PHPWord = PHPWord_IOFactory::load($source); + +// (Re)write contents +$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); +foreach ($writers as $writer => $extension) { + echo date('H:i:s'), " Write to {$writer} format", EOL; + $objWriter = PHPWord_IOFactory::createWriter($PHPWord, $writer); + $objWriter->save("{$name}.{$extension}"); + rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +} + +// Done +echo date('H:i:s'), " Done writing file(s)", EOL; +echo date('H:i:s'), " Peak memory usage: ", (memory_get_peak_usage(true) / 1024 / 1024), " MB", EOL; diff --git a/samples/old/HeaderFooter.php b/samples/Sample_12_HeaderFooter.php old mode 100755 new mode 100644 similarity index 55% rename from samples/old/HeaderFooter.php rename to samples/Sample_12_HeaderFooter.php index ae3ce5accb..b0d0e13792 --- a/samples/old/HeaderFooter.php +++ b/samples/Sample_12_HeaderFooter.php @@ -1,7 +1,11 @@ '); +require_once '../Classes/PHPWord.php'; -// New Word Document +// New Word document +echo date('H:i:s') , " Create new PHPWord object" , EOL; $PHPWord = new PHPWord(); // New portrait section @@ -13,7 +17,10 @@ $table = $header->addTable(); $table->addRow(); $table->addCell(4500)->addText('This is the header.'); -$table->addCell(4500)->addImage('_earth.jpg', array('width'=>50, 'height'=>50, 'align'=>'right')); +$table->addCell(4500)->addImage( + 'resources/PHPWord.png', + array('width' => 80, 'height' => 80, 'align' => 'right') +); // Add header for all other pages $subsequent = $section->createHeader(); @@ -21,7 +28,7 @@ // Add footer $footer = $section->createFooter(); -$footer->addPreserveText('Page {PAGE} of {NUMPAGES}.', array('align'=>'center')); +$footer->addPreserveText('Page {PAGE} of {NUMPAGES}.', array('align' => 'center')); // Write some text $section->addTextBreak(); @@ -51,6 +58,17 @@ $section2->addTextBreak(); $section2->addText('Some text...'); -// Save File -$objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'Word2007'); -$objWriter->save('HeaderFooter.docx'); + +// Save file +$name = basename(__FILE__, '.php'); +$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); +foreach ($writers as $writer => $extension) { + echo date('H:i:s'), " Write to {$writer} format", EOL; + $objWriter = PHPWord_IOFactory::createWriter($PHPWord, $writer); + $objWriter->save("{$name}.{$extension}"); + rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +} + +// Done +echo date('H:i:s'), " Done writing file(s)", EOL; +echo date('H:i:s'), " Peak memory usage: ", (memory_get_peak_usage(true) / 1024 / 1024), " MB", EOL; diff --git a/samples/Sample_13_Images.php b/samples/Sample_13_Images.php new file mode 100644 index 0000000000..0f64cb7bb8 --- /dev/null +++ b/samples/Sample_13_Images.php @@ -0,0 +1,42 @@ +'); +require_once '../Classes/PHPWord.php'; + +// New Word document +echo date('H:i:s'), " Create new PHPWord object", EOL; +$PHPWord = new PHPWord(); + +// Begin code +$section = $PHPWord->createSection(); +$section->addText('Local image without any styles:'); +$section->addImage('resources/_mars.jpg'); +$section->addTextBreak(2); +// +$section->addText('Local image with styles:'); +$section->addImage('resources/_earth.jpg', array('width' => 210, 'height' => 210, 'align' => 'center')); +$section->addTextBreak(2); + +$source = 'http://php.net/images/logos/php-med-trans-light.gif'; +$section->addText("Remote image from: {$source}"); +$section->addMemoryImage($source); +// End code + +// Save file +$name = basename(__FILE__, '.php'); +$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); +foreach ($writers as $writer => $extension) { + echo date('H:i:s'), " Write to {$writer} format", EOL; + $objWriter = PHPWord_IOFactory::createWriter($PHPWord, $writer); + $objWriter->save("{$name}.{$extension}"); + rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +} + +// Done +echo date('H:i:s'), " Done writing file(s)", EOL; +echo date('H:i:s'), " Peak memory usage: ", (memory_get_peak_usage(true) / 1024 / 1024), " MB", EOL; diff --git a/samples/old/ListItem.php b/samples/Sample_14_ListItem.php old mode 100755 new mode 100644 similarity index 66% rename from samples/old/ListItem.php rename to samples/Sample_14_ListItem.php index e0125980fb..fa64878407 --- a/samples/old/ListItem.php +++ b/samples/Sample_14_ListItem.php @@ -1,10 +1,18 @@ '); +require_once '../Classes/PHPWord.php'; + +// New Word document +echo date('H:i:s'), " Create new PHPWord object", EOL; $PHPWord = new PHPWord(); -// New portrait section +// Begin code $section = $PHPWord->createSection(); // Add listitem elements @@ -41,6 +49,18 @@ $section->addListItem('List Item 6', 1, 'myOwnStyle', $listStyle, 'P-Style'); $section->addListItem('List Item 7', 0, 'myOwnStyle', $listStyle, 'P-Style'); -// Save File -$objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'Word2007'); -$objWriter->save('ListItem.docx'); +// End code + +// Save file +$name = basename(__FILE__, '.php'); +$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); +foreach ($writers as $writer => $extension) { + echo date('H:i:s'), " Write to {$writer} format", EOL; + $objWriter = PHPWord_IOFactory::createWriter($PHPWord, $writer); + $objWriter->save("{$name}.{$extension}"); + rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +} + +// Done +echo date('H:i:s'), " Done writing file(s)", EOL; +echo date('H:i:s'), " Peak memory usage: ", (memory_get_peak_usage(true) / 1024 / 1024), " MB", EOL; diff --git a/samples/Sample_15_Link.php b/samples/Sample_15_Link.php new file mode 100644 index 0000000000..ef631906d9 --- /dev/null +++ b/samples/Sample_15_Link.php @@ -0,0 +1,40 @@ +'); +require_once '../Classes/PHPWord.php'; + +// New Word document +echo date('H:i:s'), " Create new PHPWord object", EOL; +$PHPWord = new PHPWord(); + +// Begin code +$section = $PHPWord->createSection(); + +// Add hyperlink elements +$section->addLink('http://www.google.com', 'Best search engine', array('color'=>'0000FF', 'underline'=>PHPWord_Style_Font::UNDERLINE_SINGLE)); +$section->addTextBreak(2); + +$PHPWord->addLinkStyle('myOwnLinkStyle', array('bold'=>true, 'color'=>'808000')); +$section->addLink('http://www.bing.com', null, 'myOwnLinkStyle'); +$section->addLink('http://www.yahoo.com', null, 'myOwnLinkStyle'); + +// End code + +// Save file +$name = basename(__FILE__, '.php'); +$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); +foreach ($writers as $writer => $extension) { + echo date('H:i:s'), " Write to {$writer} format", EOL; + $objWriter = PHPWord_IOFactory::createWriter($PHPWord, $writer); + $objWriter->save("{$name}.{$extension}"); + rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +} + +// Done +echo date('H:i:s'), " Done writing file(s)", EOL; +echo date('H:i:s'), " Peak memory usage: ", (memory_get_peak_usage(true) / 1024 / 1024), " MB", EOL; diff --git a/samples/Sample_16_Object.php b/samples/Sample_16_Object.php new file mode 100644 index 0000000000..e04c49e54d --- /dev/null +++ b/samples/Sample_16_Object.php @@ -0,0 +1,35 @@ +'); +require_once '../Classes/PHPWord.php'; + +// New Word document +echo date('H:i:s'), " Create new PHPWord object", EOL; +$PHPWord = new PHPWord(); + +// Begin code +$section = $PHPWord->createSection(); +$section->addText('You can open this OLE object by double clicking on the icon:'); +$section->addTextBreak(2); +$section->addObject('resources/_sheet.xls'); + +// End code + +// Save file +$name = basename(__FILE__, '.php'); +$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); +foreach ($writers as $writer => $extension) { + echo date('H:i:s'), " Write to {$writer} format", EOL; + $objWriter = PHPWord_IOFactory::createWriter($PHPWord, $writer); + $objWriter->save("{$name}.{$extension}"); + rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +} + +// Done +echo date('H:i:s'), " Done writing file(s)", EOL; +echo date('H:i:s'), " Peak memory usage: ", (memory_get_peak_usage(true) / 1024 / 1024), " MB", EOL; diff --git a/samples/old/TitleTOC.php b/samples/Sample_17_TitleTOC.php old mode 100755 new mode 100644 similarity index 53% rename from samples/old/TitleTOC.php rename to samples/Sample_17_TitleTOC.php index 376d26e844..efa756e4df --- a/samples/old/TitleTOC.php +++ b/samples/Sample_17_TitleTOC.php @@ -1,10 +1,18 @@ '); +require_once '../Classes/PHPWord.php'; + +// New Word document +echo date('H:i:s'), " Create new PHPWord object", EOL; $PHPWord = new PHPWord(); -// New portrait section +// Begin code $section = $PHPWord->createSection(); // Define the TOC font style @@ -41,8 +49,19 @@ $section->addTitle('I am a Subtitle of Title 3', 2); $section->addText('Again and again, more text...'); -echo 'Note: The pagenumbers in the TOC doesnt refresh automatically.'; +echo date('H:i:s'), " Note: Please refresh TOC manually.", EOL; +// End code + +// Save file +$name = basename(__FILE__, '.php'); +$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); +foreach ($writers as $writer => $extension) { + echo date('H:i:s'), " Write to {$writer} format", EOL; + $objWriter = PHPWord_IOFactory::createWriter($PHPWord, $writer); + $objWriter->save("{$name}.{$extension}"); + rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +} -// Save File -$objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'Word2007'); -$objWriter->save('TitleTOC.docx'); +// Done +echo date('H:i:s'), " Done writing file(s)", EOL; +echo date('H:i:s'), " Peak memory usage: ", (memory_get_peak_usage(true) / 1024 / 1024), " MB", EOL; diff --git a/samples/Sample_18_Watermark.php b/samples/Sample_18_Watermark.php new file mode 100644 index 0000000000..8332bd0330 --- /dev/null +++ b/samples/Sample_18_Watermark.php @@ -0,0 +1,36 @@ +'); +require_once '../Classes/PHPWord.php'; + +// New Word document +echo date('H:i:s'), " Create new PHPWord object", EOL; +$PHPWord = new PHPWord(); + +// Begin code + +$section = $PHPWord->createSection(); +$header = $section->createHeader(); +$header->addWatermark('resources/_earth.jpg', array('marginTop' => 200, 'marginLeft' => 55)); +$section->addText('The header reference to the current section includes a watermark image.'); + +// End code + +// Save file +$name = basename(__FILE__, '.php'); +$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); +foreach ($writers as $writer => $extension) { + echo date('H:i:s'), " Write to {$writer} format", EOL; + $objWriter = PHPWord_IOFactory::createWriter($PHPWord, $writer); + $objWriter->save("{$name}.{$extension}"); + rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +} + +// Done +echo date('H:i:s'), " Done writing file(s)", EOL; +echo date('H:i:s'), " Peak memory usage: ", (memory_get_peak_usage(true) / 1024 / 1024), " MB", EOL; diff --git a/samples/Sample_19_TextBreak.php b/samples/Sample_19_TextBreak.php new file mode 100644 index 0000000000..17299601c6 --- /dev/null +++ b/samples/Sample_19_TextBreak.php @@ -0,0 +1,49 @@ +'); +require_once '../Classes/PHPWord.php'; + +// New Word document +echo date('H:i:s'), " Create new PHPWord object", EOL; +$PHPWord = new PHPWord(); + +// Begin code +$fontStyle = array('size' => 24); +$paragraphStyle = array('spacing' => 240, 'size' => 24); +$PHPWord->addFontStyle('fontStyle', array('size' => 9)); +$PHPWord->addParagraphStyle('paragraphStyle', array('spacing' => 480)); +$fontStyle = array('size' => 24); + +$section = $PHPWord->createSection(); +$section->addText('Text break with no style:'); +$section->addTextBreak(); +$section->addText('Text break with defined font style:'); +$section->addTextBreak(1, 'fontStyle'); +$section->addText('Text break with defined paragraph style:'); +$section->addTextBreak(1, null, 'paragraphStyle'); +$section->addText('Text break with inline font style:'); +$section->addTextBreak(1, $fontStyle); +$section->addText('Text break with inline paragraph style:'); +$section->addTextBreak(1, null, $paragraphStyle); +$section->addText('Done.'); + +// End code + +// Save file +$name = basename(__FILE__, '.php'); +$writers = array('Word2007' => 'docx', 'ODText' => 'odt', 'RTF' => 'rtf'); +foreach ($writers as $writer => $extension) { + echo date('H:i:s'), " Write to {$writer} format", EOL; + $objWriter = PHPWord_IOFactory::createWriter($PHPWord, $writer); + $objWriter->save("{$name}.{$extension}"); + rename("{$name}.{$extension}", "results/{$name}.{$extension}"); +} + +// Done +echo date('H:i:s'), " Done writing file(s)", EOL; +echo date('H:i:s'), " Peak memory usage: ", (memory_get_peak_usage(true) / 1024 / 1024), " MB", EOL; diff --git a/samples/old/AdvancedTable.php b/samples/old/AdvancedTable.php deleted file mode 100755 index 021cd9201b..0000000000 --- a/samples/old/AdvancedTable.php +++ /dev/null @@ -1,52 +0,0 @@ -createSection(); - -// Define table style arrays -$styleTable = array('borderSize'=>6, 'borderColor'=>'006699', 'cellMargin'=>80); -$styleFirstRow = array('borderBottomSize'=>18, 'borderBottomColor'=>'0000FF', 'bgColor'=>'66BBFF'); - -// Define cell style arrays -$styleCell = array('valign'=>'center'); -$styleCellBTLR = array('valign'=>'center', 'textDirection'=>PHPWord_Style_Cell::TEXT_DIR_BTLR); - -// Define font style for first row -$fontStyle = array('bold'=>true, 'align'=>'center'); - -// Add table style -$PHPWord->addTableStyle('myOwnTableStyle', $styleTable, $styleFirstRow); - -// Add table -$table = $section->addTable('myOwnTableStyle'); - -// Add row -$table->addRow(900); - -// Add cells -$table->addCell(2000, $styleCell)->addText('Row 1', $fontStyle); -$table->addCell(2000, $styleCell)->addText('Row 2', $fontStyle); -$table->addCell(2000, $styleCell)->addText('Row 3', $fontStyle); -$table->addCell(2000, $styleCell)->addText('Row 4', $fontStyle); -$table->addCell(500, $styleCellBTLR)->addText('Row 5', $fontStyle); - -// Add more rows / cells -for($i = 1; $i <= 10; $i++) { - $table->addRow(); - $table->addCell(2000)->addText("Cell $i"); - $table->addCell(2000)->addText("Cell $i"); - $table->addCell(2000)->addText("Cell $i"); - $table->addCell(2000)->addText("Cell $i"); - - $text = ($i % 2 == 0) ? 'X' : ''; - $table->addCell(500)->addText($text); -} - - -// Save File -$objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'Word2007'); -$objWriter->save('AdvancedTable.docx'); diff --git a/samples/old/BasicTable.php b/samples/old/BasicTable.php deleted file mode 100755 index 6bd8336aa3..0000000000 --- a/samples/old/BasicTable.php +++ /dev/null @@ -1,25 +0,0 @@ -createSection(); - -// Add table -$table = $section->addTable(); - -for($r = 1; $r <= 10; $r++) { // Loop through rows - // Add row - $table->addRow(); - - for($c = 1; $c <= 5; $c++) { // Loop through cells - // Add Cell - $table->addCell(1750)->addText("Row $r, Cell $c"); - } -} - -// Save File -$objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'Word2007'); -$objWriter->save('BasicTable.docx'); diff --git a/samples/old/Image.php b/samples/old/Image.php deleted file mode 100755 index 5018e20688..0000000000 --- a/samples/old/Image.php +++ /dev/null @@ -1,23 +0,0 @@ -createSection(); - -// Add image elements -$section->addImage('_mars.jpg'); -$section->addTextBreak(2); - -$section->addImage('_earth.jpg', array('width'=>210, 'height'=>210, 'align'=>'center')); -$section->addTextBreak(2); - -$section->addImage('_mars.jpg', array('width'=>100, 'height'=>100, 'align'=>'right')); - - - -// Save File -$objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'Word2007'); -$objWriter->save('Image.docx'); diff --git a/samples/old/Link.php b/samples/old/Link.php deleted file mode 100755 index 8ad5575e9d..0000000000 --- a/samples/old/Link.php +++ /dev/null @@ -1,23 +0,0 @@ -createSection(); - -// Add hyperlink elements -$section->addLink('http://www.google.com', 'Best search engine', array('color'=>'0000FF', 'underline'=>PHPWord_Style_Font::UNDERLINE_SINGLE)); -$section->addTextBreak(2); - -$PHPWord->addLinkStyle('myOwnLinkStyle', array('bold'=>true, 'color'=>'808000')); -$section->addLink('http://www.bing.com', null, 'myOwnLinkStyle'); -$section->addLink('http://www.yahoo.com', null, 'myOwnLinkStyle'); - - - - -// Save File -$objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'Word2007'); -$objWriter->save('Link.docx'); diff --git a/samples/old/Object.php b/samples/old/Object.php deleted file mode 100755 index b54df97147..0000000000 --- a/samples/old/Object.php +++ /dev/null @@ -1,19 +0,0 @@ -createSection(); - -// Add text elements -$section->addText('You can open this OLE object by double clicking on the icon:'); -$section->addTextBreak(2); - -// Add object -$section->addObject('_sheet.xls'); - -// Save File -$objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'Word2007'); -$objWriter->save('Object.docx'); diff --git a/samples/old/Section.php b/samples/old/Section.php deleted file mode 100755 index 875e9fc27c..0000000000 --- a/samples/old/Section.php +++ /dev/null @@ -1,25 +0,0 @@ -createSection(array('borderColor'=>'00FF00', 'borderSize'=>12)); -$section->addText('I am placed on a default section.'); - -// New landscape section -$section = $PHPWord->createSection(array('orientation'=>'landscape')); -$section->addText('I am placed on a landscape section. Every page starting from this section will be landscape style.'); -$section->addPageBreak(); -$section->addPageBreak(); - -// New portrait section -$section = $PHPWord->createSection(array('marginLeft'=>600, 'marginRight'=>600, 'marginTop'=>600, 'marginBottom'=>600)); -$section->addText('This section uses other margins.'); - - - -// Save File -$objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'Word2007'); -$objWriter->save('Section.docx'); diff --git a/samples/old/Template.php b/samples/old/Template.php deleted file mode 100755 index 1b4472b16c..0000000000 --- a/samples/old/Template.php +++ /dev/null @@ -1,22 +0,0 @@ -loadTemplate('Template.docx'); - -$document->setValue('Value1', 'Sun'); -$document->setValue('Value2', 'Mercury'); -$document->setValue('Value3', 'Venus'); -$document->setValue('Value4', 'Earth'); -$document->setValue('Value5', 'Mars'); -$document->setValue('Value6', 'Jupiter'); -$document->setValue('Value7', 'Saturn'); -$document->setValue('Value8', 'Uranus'); -$document->setValue('Value9', 'Neptun'); -$document->setValue('Value10', 'Pluto'); - -$document->setValue('weekday', date('l')); -$document->setValue('time', date('H:i')); - -$document->save('Solarsystem.docx'); diff --git a/samples/old/Textrun.php b/samples/old/Textrun.php deleted file mode 100755 index 3fa12d97e3..0000000000 --- a/samples/old/Textrun.php +++ /dev/null @@ -1,31 +0,0 @@ -createSection(); - -// Add style definitions -$PHPWord->addParagraphStyle('pStyle', array('spacing'=>100)); -$PHPWord->addFontStyle('BoldText', array('bold'=>true)); -$PHPWord->addFontStyle('ColoredText', array('color'=>'FF8080')); -$PHPWord->addLinkStyle('NLink', array('color'=>'0000FF', 'underline'=>PHPWord_Style_Font::UNDERLINE_SINGLE)); - -// Add text elements -$textrun = $section->createTextRun('pStyle'); - -$textrun->addText('Each textrun can contain native text or link elements.'); -$textrun->addText(' No break is placed after adding an element.', 'BoldText'); -$textrun->addText(' All elements are placed inside a paragraph with the optionally given p-Style.', 'ColoredText'); -$textrun->addText(' The best search engine: '); -$textrun->addLink('http://www.google.com', null, 'NLink'); -$textrun->addText('. Also not bad: '); -$textrun->addLink('http://www.bing.com', null, 'NLink'); - - - -// Save File -$objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'Word2007'); -$objWriter->save('Textrun.docx'); diff --git a/samples/old/Watermark.php b/samples/old/Watermark.php deleted file mode 100755 index 319221c13e..0000000000 --- a/samples/old/Watermark.php +++ /dev/null @@ -1,20 +0,0 @@ -createSection(); - -// Create header -$header = $section->createHeader(); - -// Add a watermark to the header -$header->addWatermark('_earth.jpg', array('marginTop'=>200, 'marginLeft'=>55)); - -$section->addText('The header reference to the current section includes a watermark image.'); - -// Save File -$objWriter = PHPWord_IOFactory::createWriter($PHPWord, 'Word2007'); -$objWriter->save('Watermark.docx'); diff --git a/samples/resources/PHPWord.png b/samples/resources/PHPWord.png new file mode 100644 index 0000000000..9b7f4930f4 Binary files /dev/null and b/samples/resources/PHPWord.png differ diff --git a/samples/resources/Sample_07_TemplateCloneRow.docx b/samples/resources/Sample_07_TemplateCloneRow.docx new file mode 100755 index 0000000000..25a8c418b6 Binary files /dev/null and b/samples/resources/Sample_07_TemplateCloneRow.docx differ diff --git a/samples/resources/Sample_11_ReadWord2007.docx b/samples/resources/Sample_11_ReadWord2007.docx new file mode 100644 index 0000000000..fe8ec7acae Binary files /dev/null and b/samples/resources/Sample_11_ReadWord2007.docx differ diff --git a/samples/old/_earth.jpg b/samples/resources/_earth.jpg similarity index 100% rename from samples/old/_earth.jpg rename to samples/resources/_earth.jpg diff --git a/samples/resources/_mars.jpg b/samples/resources/_mars.jpg new file mode 100644 index 0000000000..584d3171c9 Binary files /dev/null and b/samples/resources/_mars.jpg differ diff --git a/samples/resources/_sheet.xls b/samples/resources/_sheet.xls new file mode 100644 index 0000000000..6be0305dfb Binary files /dev/null and b/samples/resources/_sheet.xls differ diff --git a/samples/results/.gitkeep b/samples/results/.gitkeep new file mode 100644 index 0000000000..e69de29bb2