Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
open-document
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Container registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
lib
unicaen
open-document
Commits
d9fd6f7a
You need to sign in or sign up before continuing.
Commit
d9fd6f7a
authored
6 years ago
by
Laurent Lecluse
Browse files
Options
Downloads
Patches
Plain Diff
Le publish ne remplacait plus les variables en entête de PDP
parent
081f8642
No related branches found
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/Document.php
+322
-558
322 additions, 558 deletions
src/Document.php
with
322 additions
and
558 deletions
src/Document.php
+
322
−
558
View file @
d9fd6f7a
...
...
@@ -2,196 +2,107 @@
namespace
Unicaen\OpenDocument
;
use
Exception
;
use
DOMDocument
;
use
DOMElement
;
use
DOMNode
;
use
DOMNodeList
;
use
Exception
;
use
ZipArchive
;
class
Document
class
Publisher
{
const
PAGE_BREAK_NAME
=
'UNICAEN_PAGE_BREAK'
;
/**
* @var ZipArchive
*/
private
$archive
;
/**
* @var bool
*/
private
$pdfOutput
=
false
;
const
PARAGRAPH
=
'text:p'
;
const
TABLE_ROW
=
'table:table-row'
;
/**
* @var Publisher
*/
private
$publisher
;
/**
* @var Stylist
*/
private
$stylist
;
/**
* @var DomDocument;
*/
private
$meta
;
/**
* @var DOMDocument
* Lecteur de fichier OpenDocument
*
* @var Document
*/
private
$
styles
;
private
$
document
;
/**
* Contenu XML du corps de texte
*
* @var DOMDocument
*/
private
$content
;
/**
* @var array
*/
private
$namespaces
=
[];
/**
* @var bool
*/
private
$metaChanged
=
false
;
/**
* @var bool
*/
private
$stylesChanged
=
false
;
/**
* @var bool
*/
private
$contentChanged
=
false
;
/**
* @var string
* @var DOMElement
*/
private
$
convCommand
=
'unoconv -f pdf -o :outputFile :inputFile'
;
private
$
body
;
/**
* @var string
* Ajoute un saut de page automatiquement entre deux instances de document lors du publipostage
*
* @var boolean
*/
private
$
tmpDir
;
private
$
autoBreak
=
true
;
/**
* @var array
*/
private
$formatters
=
[];
private
$values
=
[];
/**
* @var array
* Variable contenant le résultat final du content.xml
*
* @var string
*/
private
$tmpFiles
=
[];
private
$defaultNamespaces
=
[
'office'
=>
"urn:oasis:names:tc:opendocument:xmlns:office:1.0"
,
'style'
=>
"urn:oasis:names:tc:opendocument:xmlns:style:1.0"
,
'text'
=>
"urn:oasis:names:tc:opendocument:xmlns:text:1.0"
,
'table'
=>
"urn:oasis:names:tc:opendocument:xmlns:table:1.0"
,
'draw'
=>
"urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"
,
'fo'
=>
"urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"
,
'xlink'
=>
"http://www.w3.org/1999/xlink"
,
'dc'
=>
"http://purl.org/dc/elements/1.1/"
,
'meta'
=>
"urn:oasis:names:tc:opendocument:xmlns:meta:1.0"
,
'number'
=>
"urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"
,
'svg'
=>
"urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"
,
'chart'
=>
"urn:oasis:names:tc:opendocument:xmlns:chart:1.0"
,
'dr3d'
=>
"urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0"
,
'math'
=>
"http://www.w3.org/1998/Math/MathML"
,
'form'
=>
"urn:oasis:names:tc:opendocument:xmlns:form:1.0"
,
'script'
=>
"urn:oasis:names:tc:opendocument:xmlns:script:1.0"
,
'ooo'
=>
"http://openoffice.org/2004/office"
,
'ooow'
=>
"http://openoffice.org/2004/writer"
,
'oooc'
=>
"http://openoffice.org/2004/calc"
,
'dom'
=>
"http://www.w3.org/2001/xml-events"
,
'rpt'
=>
"http://openoffice.org/2005/report"
,
'of'
=>
"urn:oasis:names:tc:opendocument:xmlns:of:1.2"
,
'xhtml'
=>
"http://www.w3.org/1999/xhtml"
,
'grddl'
=>
"http://www.w3.org/2003/g/data-view#"
,
'officeooo'
=>
"http://openoffice.org/2009/office"
,
'tableooo'
=>
"http://openoffice.org/2009/table"
,
'drawooo'
=>
"http://openoffice.org/2010/draw"
,
'calcext'
=>
"urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0"
,
'css3t'
=>
"http://www.w3.org/TR/css3-text/"
,
'xforms'
=>
'http://www.w3.org/2002/xforms'
,
'xsd'
=>
'http://www.w3.org/2001/XMLSchema'
,
'xsi'
=>
'http://www.w3.org/2001/XMLSchema-instance'
,
'loext'
=>
'urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0'
,
'field'
=>
'urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0'
,
'formx'
=>
'urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0'
,
];
private
$outContent
;
/**
* @return ZipArchive
* @throws Exception
* @var bool
*/
public
function
getArchive
():
ZipArchive
{
if
(
!
$this
->
archive
)
{
throw
new
\Exception
(
"Aucun document n\'est chargé"
);
}
return
$this
->
archive
;
}
private
$published
=
false
;
/**
* @return
DOM
Document
* @return Document
*/
public
function
get
Cont
ent
():
DOM
Document
public
function
get
Docum
ent
():
Document
{
return
$this
->
cont
ent
;
return
$this
->
docum
ent
;
}
/**
* @return DOMDocument
* @param Document $document
*
* @return Publisher
*/
public
function
g
et
Styles
():
DOMDocument
public
function
s
et
Document
(
Document
$document
):
Publisher
{
return
$this
->
styles
;
}
$this
->
document
=
$document
;
/**
* @return DOMDocument
*/
public
function
getMeta
():
DOMDocument
{
return
$this
->
meta
;
return
$this
;
}
/**
* @return
bool
* @return
DOMElement
*/
public
function
isPdfOutput
():
bool
public
function
getBody
():
DOMElement
{
return
$this
->
pdfOutput
;
return
$this
->
body
;
}
/**
*
@param bool $pdfOutput
*
Peuple l'instance courante du document et l'ajoute à la suite du fichier
*
* @
return Document
* @
param array $values
*/
public
function
setPdfOutput
(
bool
$pdfOutput
):
Document
public
function
add
(
array
$values
):
Publisher
{
$this
->
pdfOutput
=
$pdfOutput
;
$this
->
values
[]
=
$values
;
return
$this
;
}
...
...
@@ -199,23 +110,21 @@ class Document
/**
* @return
bool
* @return
array
*/
public
function
isMetaChanged
():
bool
public
function
getValues
():
array
{
return
$this
->
metaChanged
;
return
$this
->
values
;
}
/**
* @param bool $metaChanged
*
* @return Document
* @param array $values
*/
public
function
set
MetaChanged
(
bool
$metaChanged
):
Document
public
function
set
Values
(
array
$values
):
Publisher
{
$this
->
metaChanged
=
$metaChanged
;
$this
->
values
=
$values
;
return
$this
;
}
...
...
@@ -225,21 +134,21 @@ class Document
/**
* @return bool
*/
public
function
is
StylesChanged
():
bool
public
function
is
AutoBreak
():
bool
{
return
$this
->
stylesChanged
;
return
$this
->
autoBreak
;
}
/**
* @param bool $
stylesChanged
* @param bool $
autoBreak
*
* @return
Document
* @return
Publisher
*/
public
function
set
StylesChanged
(
bool
$stylesChanged
):
Document
public
function
set
AutoBreak
(
bool
$autoBreak
):
Publisher
{
$this
->
stylesChanged
=
$stylesChanged
;
$this
->
autoBreak
=
$autoBreak
;
return
$this
;
}
...
...
@@ -247,265 +156,167 @@ class Document
/**
* @return bool
*/
public
function
isContentChanged
():
bool
{
return
$this
->
contentChanged
;
}
/**
* @param bool $contentChanged
* @param DOMElement $element
*
* @return Document
* @return Publisher
* @throws Exception
*/
public
function
s
et
ContentChanged
(
bool
$contentChanged
):
Document
public
function
g
et
Variables
(
DOMElement
$element
):
array
{
$this
->
contentChanged
=
$contentChanged
;
return
$this
;
}
$textNs
=
$this
->
getDocument
()
->
getNamespaceUrl
(
'text'
);
$variables
=
[];
$vElements
=
$element
->
getElementsByTagNameNS
(
$textNs
,
'variable-set'
);
foreach
(
$vElements
as
$vElement
)
{
$name
=
$vElement
->
getAttributeNS
(
$textNs
,
'name'
);
if
(
!
isset
(
$variables
[
$name
]))
$variables
[
$name
]
=
[];
$variables
[
$name
][]
=
$vElement
;
}
/**
* @return string
*/
public
function
getConvCommand
():
string
{
return
$this
->
convCommand
;
return
$variables
;
}
/**
* @param string $convCommand
*
* @return Document
*/
public
function
setConvCommand
(
string
$convCommand
):
Document
public
function
getSections
(
DOMElement
$element
):
array
{
$this
->
convCommand
=
$convCommand
;
return
$this
;
}
$textNs
=
$this
->
getDocument
()
->
getNamespaceUrl
(
'text'
);
$sections
=
[];
$vElements
=
$this
->
findFrom
(
$element
,
'text:section'
);
foreach
(
$vElements
as
$vElement
)
{
$name
=
$vElement
->
getAttributeNS
(
$textNs
,
'name'
);
/**
* Retourne les méta-données du fichier OpenDocument
*
* @return array
*/
public
function
getMetaArray
():
array
{
$m
=
[];
$nodes
=
$this
->
getMeta
()
->
documentElement
->
childNodes
->
item
(
0
)
->
childNodes
;
foreach
(
$nodes
as
$node
)
{
if
(
isset
(
$node
->
tagName
))
{
switch
(
$node
->
tagName
)
{
case
'meta:generator'
:
case
'meta:initial-creator'
:
case
'meta:editing-cycles'
:
case
'meta:editing-duration'
:
case
'meta:printed-by'
:
case
'dc:title'
:
case
'dc:description'
:
case
'dc:subject'
:
case
'dc:creator'
:
case
'dc:language'
:
list
(
$ns
,
$tag
)
=
explode
(
':'
,
$node
->
tagName
);
$m
[
$tag
]
=
$node
->
textContent
;
break
;
case
'meta:creation-date'
:
$m
[
'creation-date'
]
=
substr
(
$node
->
textContent
,
0
,
10
);
break
;
case
'meta:print_date'
:
$m
[
'print_date'
]
=
substr
(
$node
->
textContent
,
0
,
10
);
break
;
case
'dc:date'
:
$m
[
'date'
]
=
substr
(
$node
->
textContent
,
0
,
10
);
break
;
case
'meta:document-statistic'
:
$m
[
'document-statistic'
]
=
[];
foreach
(
$node
->
attributes
as
$attribute
)
{
$m
[
'document-statistic'
][
$attribute
->
name
]
=
$attribute
->
value
;
}
break
;
case
'meta:user-defined'
:
if
(
!
isset
(
$m
[
'user-defined'
]))
$m
[
'user-defined'
]
=
[];
foreach
(
$node
->
attributes
as
$attribute
)
{
$m
[
'user-defined'
][
$attribute
->
name
]
=
$attribute
->
value
;
}
break
;
case
'meta:keywords'
:
$m
[
'keywords'
]
=
[];
foreach
(
$node
->
childNodes
as
$knode
)
{
$m
[
'keywords'
][]
=
$knode
->
textContent
;
}
break
;
}
}
if
(
!
isset
(
$sections
[
$name
]))
$sections
[
$name
]
=
[];
$sections
[
$name
][]
=
$vElement
;
}
return
$
m
;
return
$
sections
;
}
/**
* @param string $variable
* @param mixed $value
*
* @return string
*/
public
function
formatValue
(
string
$variable
,
$value
):
string
public
function
hideSection
(
DOMElement
$section
):
Publisher
{
if
(
isset
(
$this
->
formatters
[
$variable
])
&&
$format
=
$this
->
formatters
[
$variable
]){
if
(
is_callable
(
$format
)){
$value
=
$format
(
$value
);
}
}
$section
->
parentNode
->
removeChild
(
$section
);
if
(
is_float
(
$value
)){
return
number_format
(
$value
,
2
,
','
,
' '
);
}
return
(
string
)
$value
;
return
$this
;
}
/**
* Retourne les espaces de nom associés à leurs URI respectives sous forme de tableau associatif
* @param DOMElement $element
* @param mixed $value
*
* @return
array
* @return
Publisher
*/
p
ublic
function
g
et
Namespaces
():
array
p
rotected
function
s
et
Variable
(
DOMElement
$element
,
$value
):
Publisher
{
if
(
empty
(
$this
->
namespaces
))
{
$content
=
$this
->
getArchive
()
->
getFromName
(
'content.xml'
)
;
$textNs
=
$this
->
getDocument
()
->
getNamespaceUrl
(
'text'
);
$document
=
$element
->
ownerDocument
;
$begin
=
strpos
(
$content
,
'<'
,
1
)
+
2
+
strlen
(
'office:document-content'
);
$end
=
strpos
(
$content
,
'>'
,
50
)
-
$begin
;
$content
=
explode
(
' '
,
substr
(
$content
,
$begin
,
$end
));
$this
->
namespaces
=
$this
->
defaultNamespaces
;
foreach
(
$content
as
$str
)
{
if
(
0
===
strpos
(
$str
,
'xmlns:'
))
{
$namespace
=
substr
(
$str
,
6
,
strpos
(
$str
,
'"'
)
-
7
);
$url
=
substr
(
$str
,
strpos
(
$str
,
'"'
)
+
1
,
-
1
);
$this
->
namespaces
[
$namespace
]
=
$url
;
if
(
is_string
(
$value
)
&&
false
!==
strpos
(
$value
,
"
\n
"
)){
$value
=
explode
(
"
\n
"
,
$value
);
}
else
{
$value
=
(
array
)
$value
;
}
for
(
$i
=
0
;
$i
<
count
(
$value
);
$i
++
)
{
if
(
$i
>
0
)
{
$returnVNode
=
$document
->
createElementNS
(
$textNs
,
'text:line-break'
);
$element
->
parentNode
->
insertBefore
(
$returnVNode
,
$element
);
}
$vText
=
$document
->
createTextNode
(
$this
->
getDocument
()
->
formatValue
(
$element
->
nodeValue
,
$value
[
$i
]));
$element
->
parentNode
->
insertBefore
(
$vText
,
$element
);
}
$element
->
parentNode
->
removeChild
(
$element
);
return
$this
->
namespaces
;
return
$this
;
}
/**
* @param string $name
*
* @return bool
*/
public
function
hasNamespace
(
string
$name
):
bool
private
function
addPageBreakStyle
():
Publisher
{
$this
->
getNamespaces
();
return
isset
(
$this
->
namespaces
[
$name
]);
}
/* get office:automatic-styles node */
$styles
=
$this
->
content
->
getElementsByTagNameNS
(
$this
->
getDocument
()
->
getNamespaceUrl
(
'office'
),
'automatic-styles'
)
->
item
(
0
);
$stylePageBreak
=
$this
->
newElement
(
'style:style'
,
[
'style:name'
=>
self
::
PAGE_BREAK_NAME
,
'style:family'
=>
'paragraph'
,
'style:parent-style-name'
=>
'Standard'
,
'style:master-page-name'
=>
'Standard'
,
]);
$stylePageBreakProperties
=
$this
->
newElement
(
'style:paragraph-properties'
,
[
'style:writing-mode'
=>
'page'
,
'style:page-number'
=>
'1'
,
]);
/**
* @param string $name
* @param string $url
*
* @return Document
*/
public
function
addNamespace
(
string
$name
,
string
$url
):
Document
{
if
(
!
$this
->
hasNamespace
(
$name
))
{
$this
->
namespaces
[
$name
]
=
$url
;
}
$stylePageBreak
->
appendChild
(
$stylePageBreakProperties
);
$styles
->
appendChild
(
$stylePageBreak
);
return
$this
;
}
/**
* Retourne l'url associé à un espace de nom
*
* @param string $namespace
*
* @return string
*/
public
function
getNamespaceUrl
(
string
$namespace
):
string
private
function
addPageBreak
(
DOMElement
$element
):
Publisher
{
$
n
s
=
$this
->
get
Namespaces
(
);
$
textN
s
=
$this
->
get
Document
()
->
getNamespaceUrl
(
'text'
);
if
(
!
isset
(
$ns
[
$namespace
]))
{
throw
new
Exception
(
'L\'espace de nom '
.
$namespace
.
' n\'a pas été trouvé.'
);
}
$pageBreak
=
$this
->
content
->
createElementNS
(
$textNs
,
'text:p'
);
$pageBreak
->
setAttributeNS
(
$textNs
,
'text:style-name'
,
self
::
PAGE_BREAK_NAME
);
$element
->
insertBefore
(
$pageBreak
,
$element
->
firstChild
);
return
$
ns
[
$namespace
]
;
return
$
this
;
}
/**
* Retourne un champ d'information
*
* @param integer $index
*
* @return string
* @return Publisher
* @throws Exception
*/
public
function
getInfo
(
$index
)
public
function
publishBegin
():
Publisher
{
$infonodes
=
$this
->
getMeta
()
->
getElementsByTagNameNS
(
$this
->
getNamespaceUrl
(
'meta'
),
'user-defined'
);
/* On récupère le content du document */
$this
->
content
=
new
DOMDocument
();
$this
->
content
->
loadXML
(
$this
->
getDocument
()
->
getContent
()
->
saveXML
());
return
$infonodes
->
item
(
$index
)
->
nodeValue
;
if
(
$this
->
isAutoBreak
())
{
$this
->
addPageBreakStyle
();
}
$contentText
=
$this
->
content
->
saveXML
();
$officeDocumentContentPos
=
strpos
(
$contentText
,
'<office:document-content'
);
$length
=
strpos
(
$contentText
,
'>'
,
$officeDocumentContentPos
)
+
1
;
$this
->
out
(
substr
(
$contentText
,
0
,
$length
));
/**
* Modifie un champ d'information
*
* @todo à finir d'implémenter, car ça ne marche pas!!
*
* @param integer $index
* @param string $value
*/
public
function
setInfo
(
$index
,
$value
):
Document
{
throw
new
\Exception
(
'Implémentation à corriger : ne fonctionne pas'
);
$infonodes
=
$this
->
getMeta
()
->
getElementsByTagNameNS
(
$this
->
getNamespaceUrl
(
'meta'
),
'user-defined'
);
if
(
$infonodes
->
length
>
0
)
{
$infonodes
->
item
(
$index
)
->
nodeValue
=
$value
;
$this
->
setMetaChanged
(
true
);
/* wtite all nodes, except body */
foreach
(
$this
->
content
->
documentElement
->
childNodes
as
$node
)
{
if
(
$node
->
nodeName
!=
'office:body'
)
{
$this
->
out
(
$this
->
content
->
saveXML
(
$node
));
}
return
$this
;
}
$this
->
out
(
"<office:body>"
);
/* declaration tags */
$declTags
=
[
'variable-decls'
,
'sequence-decls'
,
'user-field-decls'
,
'dde-connexion-decls'
,
];
foreach
(
$declTags
as
$tagName
)
{
$node
=
$this
->
content
->
getElementsByTagNameNS
(
$this
->
getDocument
()
->
getNamespaceUrl
(
'text'
),
$tagName
);
if
(
$node
->
length
>
0
)
{
$this
->
out
(
$this
->
content
->
saveXML
(
$node
->
item
(
0
)));
$node
->
item
(
0
)
->
parentNode
->
removeChild
(
$node
->
item
(
0
));
}
}
/**
* @param array $values
*
* @return Document
*/
public
function
publish
(
array
$values
):
Document
{
$this
->
getPublisher
()
->
setValues
(
$values
);
$this
->
getPublisher
()
->
publish
();
$this
->
body
=
$this
->
content
->
getElementsByTagNameNS
(
$this
->
getDocument
()
->
getNamespaceUrl
(
'office'
),
'text'
)[
0
];
return
$this
;
}
...
...
@@ -515,167 +326,114 @@ class Document
/**
* @return Publisher
*/
public
function
getP
ublish
er
():
Publisher
public
function
p
ublish
End
():
Publisher
{
if
(
!
$this
->
publisher
)
{
$this
->
publisher
=
new
Publisher
();
$this
->
publisher
->
setDocument
(
$this
);
}
return
$this
->
publisher
;
}
$this
->
out
(
"</office:body></office:document-content>"
);
/* On renvoie le content dans le document */
$this
->
getDocument
()
->
getArchive
()
->
addFromString
(
'content.xml'
,
$this
->
outContent
);
$this
->
published
=
true
;
/**
* @return Stylist
*/
public
function
getStylist
():
Stylist
{
if
(
!
$this
->
stylist
)
{
$this
->
stylist
=
new
Stylist
();
$this
->
stylist
->
setDocument
(
$this
);
}
return
$this
->
stylist
;
return
$this
;
}
/**
* @param $data
* @param DOMElement $element
* @param array $values
*
* @return
Document
* @return
Publisher
* @throws Exception
*/
public
function
loadFromData
(
$data
):
Document
public
function
publishValues
(
DOMElement
$element
,
array
$values
):
Publisher
{
if
(
!
class_exists
(
'ZipArchive'
)
)
{
th
row
new
Exception
(
'Zip extension not loaded'
);
if
(
$element
===
$this
->
body
)
{
$
th
is
->
getDocument
()
->
getStylist
()
->
setVariables
(
$values
);
}
$
odtFi
le
=
$this
->
tempFileName
(
'odtfile_'
,
'odt'
);
file_put_contents
(
$odtFile
,
$data
);
$
variab
le
s
=
$this
->
getVariables
(
$element
);
$sections
=
$this
->
getSections
(
$element
);
return
$this
->
loadFromFile
(
$odtFile
,
false
);
foreach
(
$values
as
$name
=>
$val
)
{
if
(
is_array
(
$val
))
{
/* On traite les données filles... */
list
(
$vname
,
$vparent
)
=
explode
(
"@"
,
$name
);
if
(
isset
(
$variables
[
$vname
]))
{
foreach
(
$variables
[
$vname
]
as
$elVar
)
{
$this
->
publishSubData
(
$elVar
,
$vparent
,
$val
);
}
/**
* @param string $fileName
* @param bool $duplicate
*
* @return Document
* @throws Exception
*/
public
function
loadFromFile
(
string
$fileName
,
bool
$duplicate
=
true
):
Document
{
if
(
!
class_exists
(
'ZipArchive'
))
{
throw
new
Exception
(
'Zip extension not loaded'
);
}
if
(
!
file_exists
(
$fileName
))
{
throw
new
Exception
(
'OpenDocument file "'
.
$fileName
.
'" doesn\'t exists.'
);
if
(
isset
(
$sections
[
$vname
]))
{
foreach
(
$sections
[
$vname
]
as
$elSec
)
{
$this
->
publishSubData
(
$elSec
,
$vparent
,
$val
);
}
}
if
(
$duplicate
)
{
$odtFile
=
$this
->
tempFileName
(
'odtFile_'
,
'odt'
);
copy
(
$fileName
,
$odtFile
);
}
else
{
$odtFile
=
$fileName
;
if
(
isset
(
$variables
[
$name
]))
{
foreach
(
$variables
[
$name
]
as
$vElement
)
{
$this
->
setVariable
(
$vElement
,
$val
?
$val
:
''
);
}
$this
->
archive
=
new
ZipArchive
();
if
(
!
true
===
$this
->
archive
->
open
(
$odtFile
,
ZIPARCHIVE
::
CREATE
))
{
throw
new
Exception
(
'OpenDocument file "'
.
$fileName
.
'" don\'t readable.'
);
}
$this
->
meta
=
new
DOMDocument
;
$this
->
meta
->
loadXML
(
$this
->
archive
->
getFromName
(
'meta.xml'
));
$this
->
styles
=
new
DOMDocument
;
$this
->
styles
->
loadXML
(
$this
->
archive
->
getFromName
(
'styles.xml'
));
$this
->
content
=
new
DOMDocument
;
$this
->
content
->
loadXML
(
$this
->
archive
->
getFromName
(
'content.xml'
));
$this
->
namespaces
=
[];
return
$this
;
if
(
false
!==
strpos
(
$name
,
'@'
))
{
list
(
$sName
,
$sType
)
=
explode
(
"@"
,
$name
);
if
(
$sType
==
'text:section'
)
{
$name
=
$sName
;
}
}
if
(
isset
(
$sections
[
$name
]))
{
foreach
(
$sections
[
$name
]
as
$sElement
)
{
if
(
$val
===
null
||
$val
===
0
||
$val
===
'0'
||
$val
===
false
||
$val
===
''
||
strtolower
(
$val
)
===
'false'
)
{
$this
->
hideSection
(
$sElement
);
}
/**
* @return string
* @throws Exception
*/
private
function
prepareSaving
(
$filename
=
null
):
string
{
if
(
$this
->
isMetaChanged
())
{
$this
->
getArchive
()
->
addFromString
(
'meta.xml'
,
$this
->
getMeta
()
->
saveXML
());
}
if
(
$this
->
isStylesChanged
())
{
$this
->
getArchive
()
->
addFromString
(
'styles.xml'
,
$this
->
getStyles
()
->
saveXML
());
}
if
(
$this
->
isContentChanged
())
{
$this
->
getArchive
()
->
addFromString
(
'content.xml'
,
$this
->
getContent
()
->
saveXML
());
}
$actualFile
=
$this
->
getArchive
()
->
filename
;
$this
->
getArchive
()
->
close
();
$this
->
archive
=
null
;
if
(
$this
->
isPdfOutput
())
{
if
(
!
$filename
)
{
$filename
=
$this
->
tempFileName
(
'odt2pdf_'
,
'pdf'
);
}
$this
->
odtToPdf
(
$actualFile
,
$filename
);
$
actualFile
=
$filename
;
if
(
$element
===
$this
->
body
)
{
$
this
->
out
(
$this
->
content
->
saveXML
(
$element
))
;
}
return
$
actualFile
;
return
$
this
;
}
/**
* @param $origine
* @param $destination
* @param DOMElement $element
* @param string $parent
* @param string $variable
*
* @return D
ocu
ment
* @return D
OMEle
ment
* @throws Exception
*/
public
function
odtToPdf
(
$origine
,
$de
stin
ation
):
Docu
ment
public
function
getSubDoc
(
DOMElement
$element
,
string
$parent
,
st
r
in
g
$variable
):
DOMEle
ment
{
$command
=
$this
->
getConvCommand
();
$command
=
str_replace
(
':inputFile'
,
$origine
,
$this
->
getConvCommand
());
$command
=
str_replace
(
':outputFile'
,
$destination
,
$command
);
exec
(
$command
,
$output
,
$return
);
if
(
0
!=
$return
)
{
throw
new
\Exception
(
'La conversion de document en PDF a échoué'
);
$variables
=
$this
->
getVariables
(
$element
);
if
(
!
isset
(
$variables
[
$variable
][
0
]))
{
throw
new
\Exception
(
'La variable "'
.
$variable
.
'"" n\'a pas été trouvée dans le document'
);
}
return
$this
;
return
$this
->
getSubDocWithVariable
(
$variables
[
$variable
][
0
],
$parent
)
;
}
/**
* @param
string $fileName
* @param
DOMElement $element
*
* @return Document
* @throws Exception
* @return Publisher
*/
public
function
saveToFile
(
string
$fileName
):
Document
public
function
remove
(
DOMElement
$element
):
Publisher
{
$
actualFile
=
$this
->
pre
pareSaving
(
$fileName
);
$
element
->
p
a
re
ntNode
->
removeChild
(
$element
);
return
$this
;
}
...
...
@@ -683,186 +441,192 @@ class Document
/**
* @return string
* @throws Exception
* @param DOMElement $subDoc
* @param array $variables
* @param DOMElement $refNode
*
* @return Publisher
*/
public
function
saveToData
():
string
public
function
publishBefore
(
DOMElement
$subDoc
,
array
$variables
,
DOMElement
$refNode
):
Publisher
{
$actualFile
=
$this
->
prepareSaving
();
$node
=
$subDoc
->
cloneNode
(
true
);
$this
->
publishValues
(
$node
,
$variables
);
$refNode
->
parentNode
->
insertBefore
(
$node
,
$refNode
);
return
file_get_contents
(
$actualFile
)
;
return
$this
;
}
/**
* @return string
* @param DOMElement $element
* @param string $parent
* @param DOMElement $variable
*
* @return DOMElement
* @throws Exception
*/
p
ublic
function
get
TmpDir
():
string
p
rivate
function
get
SubDocWithVariable
(
DOMElement
$element
,
string
$parent
):
DOMElement
{
if
(
!
$this
->
tmpDir
)
{
return
sys_get_temp_dir
();
if
(
$element
->
tagName
==
'text:section'
)
{
return
$element
;
// C'est la section qui est dupliquée
}
else
{
$i
=
10
;
$found
=
false
;
for
(
$i
=
0
;
$i
<
10
;
$i
++
)
{
$parentNode
=
isset
(
$parentNode
)
?
$parentNode
->
parentNode
:
$element
->
parentNode
;
if
(
$parentNode
->
nodeName
==
$parent
)
{
$found
=
true
;
break
;
}
}
return
$this
->
tmpDir
;
if
(
!
$found
)
{
throw
new
\Exception
(
'Le noeud parent de type '
.
$parent
.
' n\'a pas été trouvé'
);
}
return
$parentNode
;
}
}
/**
* @param string $tmpDir
* @param DOMElement $element
* @param string $parent
* @param array $values
*
* @return
Document
* @return
Publisher
*/
p
ublic
function
setTmpDir
(
string
$tmpDir
):
Document
p
rivate
function
publishSubData
(
DOMElement
$element
,
string
$parent
,
array
$values
):
Publisher
{
$this
->
tmpDir
=
$tmpDir
;
if
(
!
file_exists
(
$tmpDir
))
{
mkdir
(
$tmpDir
);
$parentNode
=
$this
->
getSubDocWithVariable
(
$element
,
$parent
);
foreach
(
$values
as
$vals
)
{
$clone
=
$parentNode
->
cloneNode
(
true
);
$this
->
publishValues
(
$clone
,
$vals
);
$parentNode
->
parentNode
->
insertBefore
(
$clone
,
$parentNode
);
}
return
$this
;
return
$this
->
remove
(
$parentNode
)
;
}
/**
* @param null $prefix
*
* @return string
* Construit le fichier final à partir des données
*/
p
rivate
function
tempFileName
(
$prefix
=
null
,
$ext
=
'odt'
):
string
p
ublic
function
publish
()
{
$tmpDir
=
$this
->
getTmpDir
();
if
(
'/'
!=
substr
(
$tmpDir
,
-
1
))
{
$tmpDir
.
=
'/'
;
$this
->
publishBegin
();
$first
=
true
;
foreach
(
$this
->
values
as
$values
)
{
$bodyNode
=
$this
->
body
->
cloneNode
(
true
);
if
(
$first
)
{
$first
=
false
;
}
elseif
(
$this
->
isAutoBreak
())
{
$this
->
addPageBreak
(
$bodyNode
);
}
$tempFileName
=
uniqid
(
$tmpDir
.
$prefix
)
.
'.'
.
$ext
;
$this
->
tmpFiles
[]
=
$tempFileName
;
$this
->
publishValues
(
$bodyNode
,
$values
);
$this
->
getDocument
()
->
getStylist
()
->
setVariables
(
$values
);
$this
->
out
(
$this
->
content
->
saveXML
(
$bodyNode
));
$first
=
false
;
}
return
$tempFileName
;
$this
->
publishEnd
()
;
}
/**
* @return array
* @param string $name
*
* @return DOMNode[]
* @throws Exception
*/
p
ublic
function
getFormatters
():
array
p
rivate
function
find
(
string
$name
):
DOMNodeList
{
return
$this
->
formatters
;
$document
=
$this
->
getDocument
();
return
$document
->
find
(
$this
->
content
,
$name
);
}
/**
* @param
string $variabl
e
* @param
mixed $format
* @param
DOMNode $nod
e
* @param
$name
*
* @return Document
* @return DOMNodeList
* @throws Exception
*/
p
ublic
function
addFormatter
(
string
$variable
,
$format
):
Documen
t
p
rivate
function
findFrom
(
DOMNode
$node
,
$name
):
DOMNodeLis
t
{
$this
->
formatters
[
$variable
]
=
$format
;
return
$this
;
return
$this
->
getDocument
()
->
find
(
$node
,
$name
);
}
/**
* PHP 5 introduces a destructor concept similar to that of other object-oriented languages, such as C++.
* The destructor method will be called as soon as all references to a particular object are removed or
* when the object is explicitly destroyed or in any order in shutdown sequence.
*
* Like constructors, parent destructors will not be called implicitly by the engine.
* In order to run a parent destructor, one would have to explicitly call parent::__destruct() in the destructor body.
*
* Note: Destructors called during the script shutdown have HTTP headers already sent.
* The working directory in the script shutdown phase can be different with some SAPIs (e.g. Apache).
*
* Note: Attempting to throw an exception from a destructor (called in the time of script termination) causes a fatal
* error.
* @param string $name
* @param array $attrs
*
* @return void
* @link https://php.net/manual/en/language.oop5.decon.php
* @return DOMElement
*/
p
ublic
function
__destruct
()
p
rivate
function
newElement
(
string
$name
,
array
$attrs
=
[]):
DOMElement
{
/* On supprime les éventuels fichiers temporaires pour libérer l'espace */
foreach
(
$this
->
tmpFiles
as
$tmpFile
)
{
if
(
file_exists
(
$tmpFile
))
{
unlink
(
$tmpFile
);
}
}
$document
=
$this
->
getDocument
();
return
$document
->
newElement
(
$this
->
content
,
$name
,
$attrs
);
}
/**
* @param $fileName
* Ajoute du contenu au fichier content.xml
* Méthode à ne pas exploiter
*
* @return Document
* @throws Exception
* @param string $xml
*/
public
function
download
(
$fileName
):
Document
public
function
out
(
$xml
)
{
$actualFile
=
$this
->
prepareSaving
();
if
(
headers_sent
())
{
throw
new
Exception
(
'Headers Allready Sent'
);
$this
->
outContent
.
=
$xml
;
}
$contentType
=
$this
->
isPdfOutput
()
?
'application/pdf'
:
'application/vnd.oasis.opendocument.text'
;
header
(
'Content-type: '
.
$contentType
);
header
(
'Content-Disposition: attachment; filename="'
.
$fileName
.
'"'
);
header
(
'Content-Transfer-Encoding: binary'
);
header
(
'Pragma: no-cache'
);
header
(
'Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0'
);
header
(
'Expires: 0'
);
readfile
(
$actualFile
);
return
$this
;
/**
* @return string
*/
public
function
getOutContent
():
string
{
return
$this
->
outContent
;
}
/**
* @param DOMNode $node
* @param string $name
*
* @return DOMNode[]
* @throws Exception
* @return bool
*/
public
function
find
(
DOMNode
$node
,
string
$name
):
DOMNodeList
public
function
isPublished
():
bool
{
list
(
$namespace
,
$name
)
=
explode
(
':'
,
$name
);
return
$node
->
getElementsByTagNameNS
(
$this
->
getNamespaceUrl
(
$namespace
),
$name
);
return
$this
->
published
;
}
/**
* @param DOMDocument $document
* @param string $name
* @param array $attrs
* @param bool $published
*
* @return DOMElement
* @throws Exception
* @return Publisher
*/
public
function
newElement
(
DOMDocument
$document
,
string
$name
,
array
$attrs
=
[]):
DOMElement
public
function
setPublished
(
bool
$published
):
Publisher
{
list
(
$namespace
)
=
explode
(
':'
,
$name
)
;
$this
->
published
=
$published
;
$newNode
=
$document
->
createElementNS
(
$this
->
getNamespaceUrl
(
$namespace
),
$name
);
foreach
(
$attrs
as
$attrName
=>
$attrValue
)
{
list
(
$attrNS
)
=
explode
(
':'
,
$attrName
);
$newNode
->
setAttributeNS
(
$this
->
getNamespaceUrl
(
$attrNS
),
$attrName
,
$attrValue
);
return
$this
;
}
return
$newNode
;
}
}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment