# OpenTBS - create OpenOffice and Ms Office documents with PHP

version 1.9.0, 2014-04-10, by Skrol29
help file modified on 2014-04-10

1. Introduction
2. Installing
3. Understanding principles
4. Synopsis and code examples
   - 4.1. Preparation of TinyButStrong Template Engine with the OpenTBS plug-in
   - 4.2. Method LoadTemplate()
   - 4.3. Method Show()
   - 4.4. Block Alias
   - 4.5. Change data of series in charts
   - 4.6. Change pictures in the document
   - 4.7. Merging data in spreadsheet cells
   - 4.8. Delete or merge columns in tables
   - 4.9. Commands to control the merging
   - 4.10. Manual modification of files in the archive
   - 4.11. Miscellaneous
5. Demo
6. Debugging your template
7. What to do if Zlib extension is not enabled with PHP?
8. Changelog
9. License

## 1. Introduction

OpenTBS is a plug-in for the TinyButStrong Template Engine.

TinyButStrong is a PHP Template Engine which has special template syntax and allows you to design templates in their natural editing tools. But it normally works only for Text files, including XML and HTML.

With TinyButStrong and its plug-in OpenTBS, you can use the template engine to merge OpenOffice documents and Ms Office documents with lot of facilities. All OpenDocument Format (ODF) and Office Open XML (OOXML) can be merged with OpenTBS, and also XPS files (XPS is a PDF competitor provided by Microsoft). In fact, all zip archives containing Xml/Html/Text files can be merged with OpenTBS.

##### What is special to OpenTBS:

- Design your templates directly with OpenOffice or MS Office.
- No exe file needed to merge documents.
- No temporary files needed to merge documents.
- Output directly as an http download, a new file on the disk, or as a string (for file attachment for example).
- Works with both PHP 4 and PHP 5.
- No PHP extension is required (If the Zlib extension is enabled it becomes easier to use templates, see more detail below)

You should know Template Engines and more specifically TinyButStrong to use OpenTBS.

## 2. Installing

##### Requirements:

- TinyButStrong version 3.8.0 or higher. (OpenTBS versions <= 1.5.0 require TinyButStrong version 3.6.0 or higher)
- PHP 4.3 or higher, PHP 5
- It is better to have the Zlib extension enabled on your PHP installation. If it's not, here is what to do.

##### Installation:

Just put the file "tbs_plugin_opentbs.php" with your PHP scripts.

## 3. Understanding principles

It is important to figure out that OpenOffice and Ms Office (since version 2007) documents are technically zip archives containing XML files, even if the extension of the document is not ".zip". Those zip archives can contain other file types like pictures or sounds, but the document structure and the text contents are saved as XML files. The XML Synopsis summarizes the key entities of XML sub-files contained in OpenOffice and Ms Office documents.

TinyButStrong can merge XML files, but cannot read zip archives by itself. The plug-in OpenTBS extends the TinyButStrong methods LoadTemplate() and Show() to make them working with zip archives. But you do not have to bother with it because OpenTBS is managing archives in a way that is invisible for you.

When the OpenTBS plugin is installed, the LoadTemplate() method becomes able to first load a zip archive (an OpenOffice or Ms Office document), and then to load the contents of any XML or Text files stored in the archive. You can then merge the contents of XML or Text files with all features of the TinyButStrong template engine. At the end, the Show() method does render the entire zip archive including modified stored files. The render can be done as an HTTP download, a news file on the server's disk, or in a PHP string.

Since OpenTBS version 1.3, you can also add and delete files in the archive. Before this version you could only modify existing files in the archive.

OpenTBS has automatic extension recognition. When you load a document which has one of the following extensions { odt, odg, ods, odf, odp, odm, docx, xlsx, pptx }, then the main XML file of the archive are automatically loaded, and some special character conversion are preset. For example, for all OpenDocument files, the stored file "content.xml" is automatically loaded.
Since version 1.6.0, if the extension is not recognized then OpenTBS also try to find the document by the sub-file presence. And if all fails, then you can force the document type using a special command.

## 4. Synopsis and code examples

### 4.1. Preparation of TinyButStrong Template Engine with the OpenTBS plug-in

include_once('tbs_class.php');
include_once('tbs_plugin_opentbs.php');
$TBS = new clsTinyButStrong;
$TBS->Plugin(TBS_INSTALL, OPENTBS_PLUGIN);

### 4.2. Method LoadTemplate()

#### • Load an archive with the automatic extension recognition (explained above):

$TBS->LoadTemplate('document.odt'); // Load the archive 'document.odt'.

#### • Load an archive without the automatic extension recognition:

(supported since OpenTBS version 1.1)
$TBS->LoadTemplate('document.odt#');

#### • Load an archive with a PHP file handle:

(supported since OpenTBS version 1.8.1)
$handle = tmpfile();
fwrite($handle, $binary_contents);
$TBS->LoadTemplate($handle);

#### • Load an archive and one file stored in this archive:

$TBS->LoadTemplate('document.odt#content.xml');

#### • Load an archive and several files stored in this archive:

$TBS->LoadTemplate('document.odt#content.xml;settings.xml');

#### • Load a stored file from the current archive:

See command OPENTBS_SELECT_FILE.

#### • Load an archive with special data conversion:

(supported since OpenTBS version 1.3.2)
$TBS->LoadTemplate('document.odt', OPENTBS_ALREADY_UTF8);

OpenTBS manages XML files that are UTF8 encoded. But by default, it assumes that all the data to merge (which can come from PHP or SQL) is Ascii encoded, and thus it performs conversions. If you want to define the data conversion, then you can use one of the following constants:

- OPENTBS_DEFAULT: OpenTBS assumes that all data is ASCII encoded,
- OPENTBS_ALREADY_UTF8: OpenTBS assumes that all data is already UTF8 encoded,
- OPENTBS_ALREADY_XML: OpenTBS assumes that all data is already XML encoded, and thus it won't convert data at all. Take care of that option.

Please note that if you need to change the data conversion for one or few fields only in your template, then you can use parameter "htmlconv" (see the TBS documentation for more details).

### 4.3. Method Show()

Render options for OpenTBS:

#### • Render the merged archive as an HTTP download: ($file_name is optional)

$TBS->Show(OPENTBS_DOWNLOAD, $file_name);

#### • Render the merged archive as an HTTP output with your customized HTTP headers:

header(...); // your custom headers here
$TBS->Show(OPENTBS_NOHEADER); // output the binary file without header

#### • Render the merged archive as a new file saved on the server's disk:

$TBS->Show(OPENTBS_FILE, $file_name);

#### • Render the merged archive as a PHP string:

(supported since OpenTBS version 1.1)
$TBS->Show(OPENTBS_STRING);
$string = $TBS->Source;

When you use OPENTBS_STRING then there is no output for the client. But instead, the binary source of the archive is placed into property $TBS->Source. This feature can be useful, for example, when you want to place the merged document into an email as an attached file.

### 4.4. Block alias

Block Alias are supported since OpenTBS version 1.8.0, they can work only with TBS 3.8.0 or higher.

The Block Alias are wrappers for defining TBS blocks on usual Libre Office and Ms Office entities.
This helps to not referring directly to XML entities and to harmonize block definitions between types of documents.
For example: you can use block=tbs:row instead of block=table:table-row.

Some Block Alias, such as tbs:page and tbs:section, are also defining an entity that you cannot have with normal XML entities.

##### Block alias available according to the type of document :

Alias | Desciption | LibreOffice | Ms Office
--- | --- | --- | ---
Writer (odt) | Calc (ods) | Impress (odp) | Word (docx) | Excel (xlsx) | PowerPoint (pptx)
tbs:p | A paragraph. | yes | no | yes | yes | no | yes
tbs:title | A title. | yes | no | yes | yes | no | yes
tbs:section | A section of text. | yes | no | no | yes | no | no
tbs:table | A table inserted in the document. | yes | a sheet | yes | yes | no | yes
tbs:row | A row of a table. | yes | yes | yes | yes | yes | yes
tbs:cell | A cell of a table. | yes | yes | yes | no | yes | yes
tbs:comment | A comment. | yes | yes | yes | no | no | no
tbs:page | A page defined by an explicit page break before a paragraph. | yes | no | no | yes | no | no
tbs:slide | A slide. | no | no | yes | no | no | no
tbs:sheet | A worksheet. | a table | yes | no | no | no | no
tbs:draw | A single draw, or set of draws (Ms Word) | yes | yes | yes | yes | yes | yes
tbs:drawgroup | A group of draws. | yes | yes | yes | yes | yes | yes
tbs:drawitem | A single draw item among a set of items. | yes | yes | yes | yes | yes | yes
tbs:listitem | An item of a bullet list. | yes | no | yes | yes | no | yes

### 4.5. Change data of series in charts

#### • Change series in charts:

(supported since OpenTBS version 1.6.0, for Ms Word and Ms Powerpoint, since version 1.8.0 for LibreOffice)
Example: $TBS->PlugIn(OPENTBS_CHART, $ChartRef, $SeriesNameOrNum, $NewValues, $NewLegend=false)

This command changes the values of a series in a Chart of the document. The chart will be automatically actualized when the merged document is opened because OpenTBS also breaks the link between the chart and its cached view. It can also delete or rename the series in the chart.

The result is true if the series is modified with success, otherwise the result is false.

Argument | Description
--- | ---
$ChartRef | This value can be either: The title of the chart (supported since OpenTBS 1.8.0). In both Ms Office and LibreOffice, that is the property "Title" of the frame that embeds the chart. The order number of the chart in the document (first is number 1). You can use the command OPENTBS_DEBUG_INFO in order to view all charts in the document that OpenTBS can manage. Deprecated since version 1.8.0: in previous version, $ChartRef could be the internal name of the XML file that contains the chart definition, with or without the extension. Such as 'chart1'.
$SeriesNumOrName | Exact caption of the series in the chart, or its number (first is number 1). Typically 'Series 1' or 1.
$NewValues | The new data of the series. Must be an array, or value false if you want to delete the series. The array can store data with 3 possibilities: #1: $NewValues = array( array('cat1', 'cat2', 'cat3', ...), array(val1, val2, val3, ...) ); or #2: $NewValues = array('cat1'=>val1, 'cat2'=>val2, 'cat3'=>val3, ...); or #3: $NewValues = array( array(x1, y1), array(x2,y2), array(x3, y3), ...); Notes : Structure #3 is supported only for LibreOffice, and is required when the chart type is XY (Scatter), Bubble or Stock. Use 2 values in each items for XY, 3 for Bubble, and 4 for Stock. Structure #1 is required for Ms Office when the chart type is XY (Scatter). Bubble and Stock are not yet supported for Ms Office.
$NewLegend | Optional. The new caption of the series.

##### Please note:

- The type of the chart cannot be changed.
- Some charts may not be recognized by this feature when the Word document is created with Word <= 2007 or is saved with a Compatibility Mode. You have to convert charts to have it work (right on the chart and choose "Convert"). You can use the command OPENTBS_DEBUG_INFO in order to view all unsupported charts in the document.
- Charts in worksheets (Ms Office and LibreOffice) are not supported. This is because such charts are linked to cells.
- With Ms Office, charts must not be linked to external data (such as Excel worksheet). Otherwise the chart will be automatically actualized back the previous values when it will be opened.

### 4.6. Change pictures in the document

#### • Change an internal picture with a new one:

(supported since OpenTBS version 1.4.0, for OpenOffice and MsOffice documents only)
Example: [onshow.x;ope=changepic]

In the example above, $x is a PHP global variable containing the name of an external picture file (relative or absolute path). Of course you can use this feature on TBS fields merged with MergeBlock().

When a TBS field having "ope=changepic" is merged in the template, then OpenTBS will search the first picture located before the field (see parameter tagpos below for another position), and then it will change the picture assuming that the value of the field is the path for a picture file on the server. You don't have to care about loading the picture file in the document, OpenTBS will manage this for you.

Note that parameter "ope=changepic" is a feature provided by the OpenTBS plug-in, which extends the "ope" parameter natively present with TBS.

Instead of change a picture with a TBS tag, you can also do it manually at the PHP side using the command OPENTBS_CHANGE_PICTURE.

Note that since OpenTBS version 1.8.0, you can change picture in Ms Excel worksheet. You must put the TBS field inside the picture description and use parameter "tagpos=inside". Before this version it was not possible to change pictures in an Ms Excel worksheet.

In order to simplify your coding, they are other complementary optional parameters:

Parameter | Description
--- | ---
tagpos | Supported values are "after", "before" and "inside". This option indicates the position of the TBS tag relativelly to the target picture. The default value is "after", it means that the TBS tag (the one with "ope=changepic") must be placed after the picture. You can use "tagpos=inside" when you put the TBS field in the Description or Title of the image (LibreOffice/OpenOffice or Ms Office). This option won't work if you put the TBS tag inside the property Name of an image in LibreOffice/OpenOffice. In Ms Word 2007, property Description and Title are supported but not available for editing, but you can use "Alternative text" (in the "Web" tab of the Size dialog box) , ot the URL, or the Toolipt of a Link on the image. In Ms Excel, you must use "tagpos=inside" because pictures are not saved in the sheet, they are not positioned relativelly to cells. Parameter tagpos is supported since OpenTBS version 1.8.0. Previsouly the TBS tag had to be placed after the picture.
from | This option reformulates the path of the new picture to insert. The parameter's value can contain the [val] keyword or any [var] fields, they work the same way as with parameter "file". Example: [onshow.x;ope=changepic;from='../pic/[val].gif']
as | This option reformulates the name of the picture that it will take inside the document. It is rare to need it, but it can help in some cases. Note that the external picture file is not renamed. The new name must be defined without path. The parameter's value can contain the [val] keyword or any [var] fields, they work the same way as with parameter "file". Example: [onshow.x;ope=changepic;as='[val].gif']
default | This option defines the picture that should be used when the expected one is not found. The parameter's value must be the path of a file on the server, or the keyword "current". If the value is "current" then OpenTBS will let the current picture of the template if the new picture is not found. Since OpenTBS version 1.8.0 the default value is "current". In prior versions, there was no default value and an OpenTBS error message was prompted if the new image was not found.
adjust | Adjust the size of the picture in the document. This parameter requires that PHP is configured with the GD extension, which is usually the case. Values can be on of the followings:
adjust (or adjust=inside) | The picture is adjusted to enter into the picture bounds of the template.
adjust=samewidth | The picture is adjusted to have the same width than the picture of the template.
adjust=sameheigth | The picture is adjusted to have the same height than the picture of the template.
adjust=100% (or another pourcentage) | The picture is adjusted to be proportional to the originial size.
Parameter adjust is supported since OpenTBS version 1.7.0.

### 4.7. Merging data in spreadsheet cells

In speaksheets (Ms Excel or LibreOffice Calc), cells values may be formated but also typed. For example, a cell value may be typed as String, Numerical, Boolean or Date.

Unfortunately, as soon as you enter a TBS tag in a cell, the cell it is typed as String by the software. This may not be corresponding to the final value you wanted after the merging.

For those situations, TBS offers a parameter like "ope=cellType". The cell type will be changed during the merging and the merged value will be implicitly converted by TBS to fit to the expected type.

##### Example:

- [onload.x;ope=tbs:num] => will turn the cell as Numerical after $x is merged.

##### Parameters for merging data in spreadsheet cells:

Expected Cell Type | Parameter | Note
--- | --- | ---
Number | ope=tbs:num |
Boolean | ope=tbs:bool |
Date/time | ope=tbs:date |
Time only | ope=tbs:time | For XLSX, it's an alias of ope=tbs:date
Currency | ope=tbs:curr | For XLSX, it's an alias of ope=tbs:num
Percentage | ope=tbs:percent | For XLSX, it's an alias of ope=tbs:num

The keywoks in the table above are supported since OpenTBS version 1.8.1.
In previous version you should use keywords: odsNum, odsBool, odsDate, odsTime, odsCurr, odsPercent, xlsxNum, xlsxBool and xlsxDate.

### 4.8. Delete or merge columns in a table

This feature is supported since OpenTBS version 1.8.0.

##### Delete columns in a table

Parameter "ope=delcol" enables you to delete the columns you want in any table of an Ms Word Document. It doesn't work for LibreOffice for now.

You have to put a TBS field anywhere inside the table with the following parameters:

- ope = delcol
- colnum = the column numbers to delete, separated with commas (first colmun is number 1).
- colshift = (optional) if parameter "colnum" has only on value then "colshift" extends the number of columns to delete to the left of to the rigth.

Both parameters "colnum" and "colshift" can contain [val] and [var] fields. When the TBS field is merged, the specified columns will be deleted and the TBS field is erased.

##### Examples:

- [onload;ope=delcol;colnum=2,4,6] => will delete columns {2,5,6}
- [onload;ope=delcol;colnum=2;colshift=2] => will delete columns {2,3,4}
- [onload;ope=delcol;colnum=2;colshift=-1] => will delete columns {1,2}
- [onload.col_to_delete;ope=delcol;colnum=[val];colshift=2] => will delete 3 colmuns staring to column number $col_to_delete

##### Merge cells in a table

Parameter "ope=mergecell" enables you to merge cells vertically in a table of an Ms Word Document. It doesn't work for LibreOffice for now.

This can work only for a block merged on the rows of the table. Note that the TBS field with "ope=mergecell" does not display any value, it only produces the merge.

##### Example:

- [b.rank;block=tbs:row][b.rank;ope=mergecell] => This will display the colmun rank and alos merge the cells vertically depending on the rank.

### 4.9. Commands to control the merging

The following commands are supported since OpenTBS version 1.7.0 :

Command | Desciption
--- | ---
For all types of documents |
$TBS->PlugIn(OPENTBS_SELECT_MAIN) | Select and load the main sub-file in the opened template. For example in a Writer document, or an Ms Word document, this command can bring you back from the merging of a header to the main body.
$TBS->PlugIn(OPENTBS_SELECT_FILE, $SubFile) | Select a sub-file in the opened template. Return false if the sub-file is not found. If the sub- file is stored in a subfolder, then indicate the full path. For example: 'word/document.xml'. Before OpenTBS 1.9.0, selecting a sub-file had to be done using $TBS->LoadTemplate('#' . $SubFile);. Command OPENTBS_SELECT_FILE is supported since OpenTBS version 1.9.0.
$TBS->PlugIn(OPENTBS_CHANGE_PICTURE, $PicRef, $File [, $Default] [, $Adjust] ) | Change one or several pictures in the current sub-file. This command does the same as the changepic feature. The difference is that the command needs no TBS tags in the template. $PicRef must be a string that is saved in the Title or the Description of the picture. If several pictures have the same key string then they are all replaced with the picture. It won't work if you put the string reference tag inside the property Name of an image in LibreOffice/OpenOffice. In Ms Word 2007, both properties Description and Title are supported but not available for editing, but you can use "Alternative text" (in the "Web" tab of the Size dialog box) , ot the URL, or the Toolipt of a Link on the image. $File must be path for picture file that will be copied inside the document. Example: $TBS->Plugin(OPENTBS_CHANGE_PICTURE, '#main_map#', 'pics/new_map.png'); Does not work with XLSX yet. Command OPENTBS_CHANGE_PICTURE is supported since OpenTBS version 1.8.0.
$TBS->PlugIn(OPENTBS_DELETE_COMMENTS) | Delete all usual user comments in the opened template.
$TBS->PlugIn(OPENTBS_DELETE_ELEMENTS, $Elements) | Delete XML elements in the current sub-file. $Elements must be an array of strings. For example: $Elements = array('w:bookmarkStart', 'w:bookmarkEnd') This will delete all bookmarks in an Ms Word document.
For documents (ODT and DOCX) |
$TBS->PlugIn(OPENTBS_SELECT_HEADER, [$Type[, $Offset]) $TBS->PlugIn(OPENTBS_SELECT_FOOTER, [$Type[, $Offset]) | Select the sub-file corresponding to the header of the footer. Return true if succeed, false if it fails. This command is useless for LibreOffice/OpenOffice because all headers and footers are saved in the main sub-file. Nevertheless using it will select the main sub-file without raising an error. Those commands do not work for XLSX or PPTX since headers and footers are saved in each sheet or slide. The command will return false. $Type must be one of the following values (default is OPENTBS_DEFAULT): OPENTBS_DEFAULT : select the default header or footer for pages in the document. OPENTBS_FIRST : select the special header or footer reserved for the first page in the document. OPENTBS_EVEN : select the special header of footer reserved for even pages in the document. $Offset can help when they are different headers and footers of the same type defined in the document. A document can have several sections and each section can have its own header and footer. But they can also have headers and footers linked to another section. Such that a document can have several headers and footers of the same type in a single document. Use the argument $Offset in order to select other one. Default value is 0. Command OPENTBS_SELECT_HEADER and OPENTBS_SELECT_FOOTER are supported since OpenTBS version 1.9.0.
$TBS->PlugIn(OPENTBS_GET_HEADERS_FOOTERS) | Return an array of all sub-file corresponding to any header and footer in the document. Command OPENTBS_GET_HEADERS_FOOTERS is supported since OpenTBS version 1.9.0.
For workbooks (ODS and XLSX) () |
$TBS->PlugIn(OPENTBS_SELECT_SHEET, $NumOrName) | Select the sub-file corresponding to $NumOrName. This command will raise an error if the opened template is not an expected document. This command is useless for LibreOffice/OpenOffice because all sheets/slides are all saved in the main sub-file. Nevertheless using it will select the main sub-file without raising an error. $NumOrName is an identifier that can be either an integer corresponding to the index of the sheet/slide, or a string corresponding to the name of the sheet/slide. Use command $TBS->PlugIn(OPENTBS_DEBUG_INFO) to list all id and name of sheets/slides in the current document. Command OPENTBS_SELECT_SLIDE is supported since OpenTBS version 1.8.0. Argument $Master is supported since OpenTBS version 1.9.0.
$TBS->PlugIn(OPENTBS_DISPLAY_SHEETS, $NumOrNames[, $Visible]) | Make one or several sheets/slides visible or hidden. This command will raise an error if the opened template is not an expected document. $NumOrNames must be an array of identifiers, or even a single identifier. See command OPENTBS_SELECT_SHEET for more details about identifiers. $Visible must be a boolean, default value is true. Command OPENTBS_DISPLAY_SLIDES is supported since OpenTBS version 1.8.0.
$TBS->PlugIn(OPENTBS_DELETE_SHEETS, $NumOrNames[, $Delete]) | Make one or several sheets te be deleted or not. This command will raise an error if the opened template is not a Workbook. $NumOrNames must be an array of identifiers, or even a single identifier. See command OPENTBS_SELECT_SHEET for more details about identifiers. $Delete must be a boolean, default value is true. Please note that for now, you must not delete a sheet that contains a Pivot Table in a XLSX workbook because this will produce an error when the workbook is opened. Command OPENTBS_DELETE_SLIDES is supported since OpenTBS version 1.8.0.
$TBS->PlugIn(OPENTBS_MERGE_SPECIAL_ITEMS) | Merge special items relatively to the current sub-file. For now, it only works with Ms Excel workbooks. This command makes automatic fields ([onload] and [onshow]) merged in pictures embedded in the current selected sheet. This can be useful for changing pictures in Ms Excel. Command OPENTBS_MERGE_SPECIAL_ITEMS is supported since OpenTBS version 1.8.0.
For presentations (ODP and PPTX) |
$TBS->PlugIn(OPENTBS_SELECT_SLIDE, $NumOrName[, $Master]) | Same as command OPENTBS_SELECT_SHEET but for slides. $Master is a boolean to indicate if you want to select a master slide in the document. Default value is false. Command OPENTBS_SELECT_SLIDE is supported since OpenTBS version 1.8.0. Argument $Master is supported since OpenTBS version 1.9.0.
$TBS->PlugIn(OPENTBS_DISPLAY_SLIDES, $NumOrNames[, $Visible]) | Same as command OPENTBS_DISPLAY_SHEET but for slides.
$TBS->PlugIn(OPENTBS_DELETE_SLIDES, $NumOrNames[, $Delete]) | Same as command OPENTBS_DELETE_SHEETS but for slides.
$TBS->PlugIn(OPENTBS_COUNT_SLIDES[, $Master]) | Return the number of slides in the presentation. Always return 0 if the document is neither a PPTX nor an ODP. $Master is a boolean to indicate if you want to count master slides in the document. Default value is false. Command OPENTBS_COUNT_SLIDES is supported since OpenTBS version 1.8.0. Argument $Master is supported since OpenTBS version 1.9.0.
$TBS->PlugIn(OPENTBS_SEARCH_IN_SLIDES, $Str[, $Options]) | Search for the string $Str trough the slides of the current document. Return the id of the first slide where the string is found. Return false if the string is not found. $Options must be a combination of the following constants. Default value is OPENTBS_FIRST. OPENTBS_FIRST : stop the search at the first slide where the string is found. OPENTBS_GO : select the corresponding slide if the string is found. OPENTBS_ALL : search through all slides and return an array of the slide ids. This command is useless for LibreOffice/OpenOffice because all slides are all saved in the main sub-file. Nevertheless using will not raise an error. Command OPENTBS_SEARCH_IN_SLIDES is supported since OpenTBS version 1.9.0.

### 4.10. Manual modification of files in the archive

#### • Check if a file does exists in the archive:

$TBS->Plugin(OPENTBS_FILEEXISTS, $Name)

Return true or false. $Name must include the inner path.
For example : $Name = 'META-INF/manifest.xml';

(supported since OpenTBS version 1.7.4)

#### • Add any new file in the archive:

// OpenTBS >= 1.6.0
$TBS->Plugin(OPENTBS_ADDFILE, $Name, $Data, $DataType=OPENTBS_STRING, $Compress=true);
// Deprecated since OpenTBS 1.6.0
$TBS->Plugin(OPENTBS_PLUGIN, OPENTBS_ADDFILE, $Name, $Data, $DataType=OPENTBS_STRING, $Compress=true);

If $Data is false then the previously add file with the given name is canceled if any.

$DataType must be OPENTBS_STRING if $Data is the content to add ; it must be OPENTBS_FILE if $Data is the path of the external file to insert.

$Compress can be true, false or an array with keys ('meth','len_u','crc32') which means that the data is already previously compressed.

(supported since OpenTBS version 1.3)

#### • Replace an existing file in the archive:

$TBS->Plugin(OPENTBS_REPLACEFILE, $Name, $Data, $DataType=OPENTBS_STRING, $Compress=true);

The arguments are the same as command OPENTBS_ADDFILE.
Please note that any TBS merge on a file in the archive will cancel previous or future replacements.

(supported since OpenTBS version 1.7.4)

#### • Delete an existing file in the archive:

// OpenTBS >= 1.6.0
$TBS->Plugin(OPENTBS_DELETEFILE, $Name);
// Deprecated since OpenTBS 1.6.0
$TBS->Plugin(OPENTBS_PLUGIN, OPENTBS_DELETEFILE, $Name);

Delete the existing file in the archive, or a file previously added using the OPENTBS_ADDFILE command.

(supported since OpenTBS version 1.3)

#### • Reset all modifications in the archive:

// OpenTBS >= 1.6.0
$TBS->Plugin(OPENTBS_RESET);
// Deprecated since OpenTBS 1.6.0
$TBS->Plugin(OPENTBS_PLUGIN, OPENTBS_RESET);

The automatic extension recognition is also applied as it was applied for the first load of the archive.

### 4.11. Miscellaneous

#### Dealing with apostrophes:

Both OpenOffice and Ms Office may automatically convert single quotes (') into typographic apostrophes (’), depending to the auto-correction options. This may be annoying when you need to code a TBS fields that have a single quote. That's why OpenTBS automatically convert by default all (’) back to single quotes (') in documents.
If you want to stop this conversion, you can set $TBS->OtbsConvertApostrophes = false; and no apostrophes will be converted. Note that you can avoid the auto-correction of single quotes (') in Ms Word using keys[ctrl]+[z], and in OpenOffice using the cancel button.

Property OtbsConvertApostrophes is supported since OpenTBS version 1.6.0.

#### • Forcing the document type recognition:

You can force the document type recognition using command OPENTBS_FORCE_DOCTYPE. Example:

$TBS->PlugIn(OPENTBS_FORCE_DOCTYPE, 'docx');

This command is supported since OpenTBS version 1.6.0.

#### • Retrieving the name of the current document:

Property $TBS->tbsCurrFile indicates the name of the current file loaded from the archive. The value is false if no file is loaded yet from the archive.

Other TinyButStrong methods and properties stay unchanged and are available for merging your template.

(supported since OpenTBS version 1.1)

## 5. Demo

The OpenTBS package includes a full set of runnable templates. Some templates can contain useful complementary information for designing.
Run the following demo under PHP: OpenTBS demo

## 6. Debugging your template

Since OpenTBS version 1.6.0, there are several commands for debugging. Please note that those commands do not exit the process.

Command | Desciption
--- | ---
$TBS->PlugIn(OPENTBS_DEBUG_INFO [, $Exit]) | Display technical information about the current loaded template, including sheet information if the template is a workbook, and chart information if the template have some. $Exit must be a boolean, default value is true.
$TBS->PlugIn(OPENTBS_DEBUG_XML_CURRENT [, $Exit]) | Display XML contents of sub-files already opened and modified for merging. XML is indented in order to improve reading. $Exit must be a boolean, default value is true.
$TBS->PlugIn(OPENTBS_DEBUG_XML_SHOW) | Ends the merge process as if the final document was created. But instead of creating the document, displays the XML contents of sub-files modified for merging. XML is indented in order to improve reading.

There is also deprecated debug options:

Command | Desciption
--- | ---
$TBS->PlugIn(OPENTBS_DEBUG_XML) | Does the same as $TBS->PlugIn(OPENTBS_DEBUG_XML_SHOW); Supported since OpenTBS version 1.3.2.
$TBS->PlugIn(OPENTBS_DEBUG_XML+OPENTBS_DEBUG_AVOIDAUTOFIELDS) | Avoid merging of [onload], [onshow] and [var].Supported since OpenTBS version 1.3.2.
$TBS->Render = OPENTBS_DEBUG_AVOIDAUTOFIELDS; | Work also in property Render.Supported since OpenTBS version 1.3.2.
$TBS->PlugIn(OPENTBS_DEBUG_CHART_LIST) | Does the same as $TBS->PlugIn(OPENTBS_DEBUG_INFO);Supported since OpenTBS version 1.6.0.

Otherwise, here are some indications that may help for the issues you can met with merging:

### a) The merged document is producing error messages when opened with its application (OpenOffice or Ms Office)

The most likely causes are:

• You've chosen the OPENTBS_DOWNLOAD render option but a php error message or any other unexpected content has been output before by PHP.

Activate the debug mode using the command OPENTBS_DEBUG_XML_SHOW, it helps to check PHP error message and other unexpected content.

• The merging has produced an invalid document or an invalid XML content in an XML file of the document.

Activate the debug mode using it helps to check the XML contents of merged files.

See section (b) below for more information in the XML structure of the files.

### b) The merged document is well opened by its application (OpenOffice or Ms Office) but the content is not designed as expected

First, you can have a look the demo templates, they contain examples and advices for each type of document.
And to go further: even if you can edit your template using directly OpenOffice or Ms Office, you will probably need to understand the XML tags and attributes to complete your merge. The file xml_synopsis.txt is a small synopsis of the XML structure you can found in the inner source of those documents. Have a look to it if you feel lost.

### c) Go deeper in the debugging

You can view the inner source of a document using a zip software like 7-Zip. It allows you to open an archive even if the extension is not ".zip".

- Open the merged document with 7-Zip (or your other zip software),
- extract the main XML file (or another file that you've merged),
- then open the XML file in an Text Editor software.
- those XML files are usually saved with no line breaks, which make them hard to be read. Some Text Editors can reformat them. You can also use the debug mode to see the formatted XML.
- check the structure of the XMK, try some fix and arrangements, deleted suspicious parts, ...
- put the modified XML file back to the archive, and test if it's correctly opened with its application (OpenOffice, Ms Office)

## 7. What to do if Zlib extension is not enabled with PHP?

OpenTBS uses Zlib functions in order to automatically uncompress and recompress files stored in the zip archive. If Zlib is not enabled, then you have to use your own uncompress/compress tool, or to prepare the template to have files uncompressed in the zip archive.

Example to uncompress the "content.xml" file in an ODT document using 7-Zip:
1) open the ODT file with 7-Zip
2) extract the "content.xml" file from the ODT file in the same folder than the ODT file
3) close 7-Zip
4) open 7-Zip, and change current directory to be the same as the ODT file
5) select the "content.xml" file and click on button [Add], or menu [File][7-Zip][Add to archive...]
6) A new window named "Add to archive" is opened,
- replace the archive name with the ODT file name,
- set the Compression level to "None".
7) Click on [Ok]
If you re-open the ODT file with 7-Zip, you can notice that the size and the uncompressed size are the same.
If the file should be placed in a sub-folder of the archive, then open the archive and rename the file in order to move it in a folder. For example rename "manifest.xml" to "META-INF\manifest.xml" will move it into META-INF. But moving the file will no delete the one which has the same name in the target folder. You have to go and delete the old one.

## 8. Changelog

### version 1.9.0, on 2014-04-10

#### Bug fixes

- Corrupted MS Office files when inserting images named with space or accent.
- XLSX warning for corrupted subfile "/xl/calcChain.xml-Part".
- Some ODS templates compatible with Ms Excel can become erroneous for Ms Excel after the merge with OpenTBS. Message "The workbook cannot be opened or repaired by Microsoft Excel because it is corrupt".
- Some XLSX templates built with LibreOffice can be very long to be opened with OpenTBS. That is because LibreOffice add some extra useless rows definition at the bottom limit of the sheets.
- A big number merged in a XLSX with parameter "ope=tbs:num" can display another value. Example : 7580563123 displays -1009371469 in 32bits.
- Inappropriate error message "ExtType is not defined" when execute a command but no template is loaded.
- OPTBS_SELECT_SHEET with an ODS template do nothing. Now it selects the main file (contains all sheets).
- OPTBS_SELECT_SLIDE with an ODP template do nothing. Now it selects the main file (contains all slides).

#### New features

- new command OPENTBS_SELECT_FILE
- new command OPENTBS_SELECT_HEADER
- new command OPENTBS_SELECT_FOOTER
- new command OPENTBS_GET_HEADERS_FOOTERS
- new command OPENTBS_SEARCH_IN_SLIDES
- new parameter $Master for command OPENTBS_SELECT_SLIDE and OPENTBS_COUNT_SLIDES

#### Enhancements

- Debug mode available even if no template is loaded.
- Debug mode display the Zlib availability.
- Based on TbsZip 2.16

### version 1.8.3, on 2014-02-02

- fixed bug: (since version 1.8.0) the changed picture is another picture in the document or an empty picture. This could happen if you used parameter "changepic" with both [onload] and [onshow] or both MergeBlock() and [onshow].

### version 1.8.2, on 2014-01-26

- fixed bug: some TBS fields seems to be ignored in ODT files edited with LibreOffice 4 or higher. This was due to a new RSID feature in LibreOffice that inserts invisible XML elements.
- fixed bug: no data displayed when merging numerical cells in ODS files built with LibreOffice 4 or higher. This was due to a new attribute in subjacent XML elements.
- Supports new parameter "parallel" of TinyButStrong 3.9.0.
- based on TbsZip 2.15

### version 1.8.1, on 2013-08-30

- new feature: the loaded template can be a PHP file handle.
- enhancement: Ms Excel Sheets are now saved with explicit references for rows and cells, so merged templates are viewable with Libre Office and other third viewers.
- enhancement: keywords for changing cell types is the same for LibreOffice and Ms Office.
- fixed bug: A DOCX file could be corrupted when using "block=tbs:page" and the last paragraph of the document has no text.
- based on TbsZip 2.14

### version 1.8.0, on 2013-05-04

- new feature: automatically cleans up spelling in PPTX templates (such information may deconstruct the TBS tags). This feature can be disabled.
- new feature: Block Alias helps to define TBS blocks easily on pages, sections,....
- new feature: merging a chart from its title.
- new parameter "tagpos" to define the position of the TBS tag realtively to the image (when using "ope=changepic").
- new parameter "delcol" to delete columns in tables.
- new parameter "mergecell" to merge cells in tables.
- enhancement: merging charts is also available for LibreOffice documents
- enhancement: when using "ope=changepic", default value of parameter "default" is now "current".
- enhancement: delete unused pictures.
- new command OPENTBS_SELECT_SLIDE
- new command OPENTBS_DELETE_SLIDES
- new command OPENTBS_DISPLAY_SLIDES
- new command OPENTBS_COUNT_SLIDES
- new command OPENTBS_MERGE_SPECIAL_ITEMS
- new command OPENTBS_CHANGE_PICTURE
- fixed bug: parameter "ope=changepic" did not work in PPTX documents.
- fixed bug: parameter "ope=changepic" did not work with [onload] fields in Ms Office.
- fixed bug: parameter "default=current" did not work when using MergeField() instead of MergeBlock().
- fixed bug: some tab may be deleted in the template (during the automatic cleanup process).
- based on TbsZip 2.13
- requires TBS 3.8.0

### version 1.7.6, on 2012-06-06

- Restore lost spaces around merged TBS fields in Ms Word documents. The patch doesn't work for headers and footers, unfortunately.

### version 1.7.5, on 2012-02-14

- Avoid erroneous Ms Word merged documents when duplicating objects such as drawings and shapes.
- Based on TbZip version 2.11
- New coding shorctut $TBS->TbsZip.
- More examples of formulas for Xlsx and Ods speadsheets.

### version 1.7.4, on 2011-10-20

- parameter "defaut=current" does not work and may build invalid documents when the target image is missing.
- new command OPENTBS_REPLACEFILE
- new command OPENTBS_FILEEXISTS

### version 1.7.3, on 2011-10-13

- fixed bug: in Ms Word documents, automatic fields (onload, onshow) placed in headers and footers with parameter "ope=changepic" are producing an erroneous merge. In Word 2010 the picture may by missing, in Word 2007 the docx file may be considered as corrupted.

### version 1.7.2, on 2011-10-12

- fixed bug: error when using command OPENTBS_SELECT_SHEET with a sheet name: Notice: Undefined index: xxx in xxx on line 1986.

### version 1.7.1, on 2011-10-07

- fixed bug: first non-empty cell of an Excel Spreadsheet is never merged if it contains a TBS field.
- minor internal improvements.

### version 1.7.0, on 2011-08-21

- new parameter 'adjust' for changing picture size
- new command OPENTBS_DEBUG_INFO
- new command OPENTBS_SELECT_MAIN
- new command OPENTBS_SELECT_SHEET
- new command OPENTBS_DISPLAY_SHEETS
- new command OPENTBS_DELETE_SHEETS
- new command OPENTBS_DELETE_COMMENTS
- new command OPENTBS_DELETE_ELEMENTS
- parameter 'changepic' is optimized

### version 1.6.2, on 2011-07-12

- fixed bug: Ms Excel cells could consider as error some formatted values such as '0.00000000000000'.

### version 1.6.1, on 2011-06-08

- fixed bug: some documents may be corrupted when created using OPENTBS_DOWNLOAD because of a PHP error "supplied argument is not a valid stream resource" or "Undefined property: clsOpenTBS::$OutputHandle".
- fixed bug: using keyword "xlsxNum", "xlsxDate" or "xlsxBool" inside a cell that is not merged can make a corrupted XLSX spreadsheet.
- improvement: updated templates in the demo.
- based on a TbsZip v2.8

### version 1.6.0, on 2011-06-07

- new feature: merge charts in Ms Word documents.
- new feature: merge rows and columns Ms Excel workbooks.
- new feature: new "ope" parameters for forcing cells type in Ms Excel (Numeric, Date and Boolean).
- new feature: debug mode enhanced.
- new feature: force the type of document using command OPENTBS_FORCE_DOCTYPE.
- new property: deal with apostrophes using property OtbsConvertApostrophes.
- improvement: if the document extension is not recognized, then try to recognize document type by sub-file presence.
- improvement: can use the Direct Command feature of TBS 3.7.0.
- based on a TbsZip v2.6

### version 1.5.0, on 2011-03-20

- new feature: headers and footers are automatically loaded for OpenOffice & MsOffice.
- new feature: automatically cleans up spelling and change trackings information in MsWord templates (such information may deconstruct the TBS tags). This feature can be disabled.
- new constant OPENTBS_DEBUG_AVOIDAUTOFIELDS
- improvement: Debug doesn't stopped if an OpenTBS alert occurs.
- improvement: OpenTBS alerts say if the process will be stopped.
- fixed bug: in debug mode: "warning function.str-repeat: Second argument has to be greater than or equal to 0"
- fixed bug: when using OPENTBS_RESET: "Warning: Missing argument 2 for clsOpenTBS::OnCommand() in ... on line 225"
- fixed bug: DML images were not found when using parameter "ope=changepic" in a DOCX document
- fixed bug: the script ends and display the XML contents when a when using parameter "ope=changepic" with a new image type in a DOCX document

### version 1.4.1, on 2010-10-28

- major bug fixed: due to TbsZip, some added or modified files can be saved the document with a wrong CRC control code. This could make softwares to consider the document as corrupted, but were often easily fixed by OpenOffice and Ms Office. Only few CRC codes are wrongly saved, thus the bug is rare and can seem to appear randomly on few documents.

### version 1.4.0, on 2010-10-05

- new parameters "changepic" and "default"

### version 1.3.3, on 2010-08-05

- property version of OpenTBS version 1.3.2 was saying 1.3.1

### version 1.3.2, on 2010-07-23

- possibility to change de default data conversion using the new constants OPENTBS_DEFAULT, OPENTBS_ALREADY_XML or OPENTBS_ALREADY_UTF8
- enhanced debug mode: listing of added, deleted and modified files ; and show XML formated contents of files merged with OpenTBS.

### version 1.3.1, on 2010-07-01

- based on TbsZip version 2.1: fixes a bug that saved a bad time of modification file was added, and saved time modification when a file content is replaced.
- the addpic operator now automatically updates the "fanifest.xml" file on OpenOffice document. Without this fix, an ODP merged document could be open with an error message with OpenOffice >= 3.2

### version 1.3, on 2010-06-01

- a new plugin command that add a new file in the archive
- a new plugin command that delete a new file in the archive
- a parameter 'ope=addpic' that add a new picture in the archive directly from the template
- based on a TbsZip v2 (modify/delete/add files in a zip archive, )

### version 1.1, on 2009-11-19

- New render option : OPENTBS_STRING
- New feature: can reset changes in the current archive using $TBS->Plugin(OPENTBS_PLUGIN, OPENTBS_RESET);
- New behavior: extension of the archive is ignored by LoadTemplate() if the name is ended with '#'
- Bug fixed: in case of several files to take from the archive in one shot, then only the last one had [onload] fields merged.

## 9. License

OpenTBS is under LGPL (Lesser General Public License)