| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353 | <?php/** * Define a docx. * @author Valentin MORREEL * @category Plugin * @license copyright */class WordExport{	public static $mime = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';	public static $extension = 'docx';	public static $description = 'Fichier de traitement de texte Word';	public $zip,$body,$header,$footer,$relationships;	public static function sample($dataset){		$rows[] = array(			'content' => 'Macros disponibles :',			'style' => array(				'bold' => true,				'font-size' => 16			)		);		foreach($dataset as $macro => $infos) {			$rows[] = array(				'content' => ($infos['type']=='list') ? '{{#'.$macro.'}}{{/'.$macro.'}} : '.$infos['desc'] : '{{'.$macro.'}} : '.$infos['desc']			);		}		$temp_file = tempnam(sys_get_temp_dir(), mt_rand(0,10000));		self::write($temp_file, $rows);		$stream = file_get_contents($temp_file);		unlink($temp_file);		return $stream;	}	/** ROOT **/	//Fichier [Content_Types].xml	public static function content_types(){		return '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/><Override PartName="/word/settings.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml"/><Override PartName="/word/webSettings.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml"/><Override PartName="/word/fontTable.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/><Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/></Types>';	}	/** DOCPROPS **/	//Fichier docProps/app.xml	public static function app(){		return '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"><Template>Normal.dotm</Template><TotalTime>0</TotalTime><Pages>1</Pages><Words>0</Words><Characters>0</Characters><Application>Microsoft Office Word</Application><DocSecurity>0</DocSecurity><Lines>1</Lines><Paragraphs>1</Paragraphs><ScaleCrop>false</ScaleCrop><HeadingPairs><vt:vector size="2" baseType="variant"><vt:variant><vt:lpstr>Titre</vt:lpstr></vt:variant><vt:variant><vt:i4>1</vt:i4></vt:variant></vt:vector></HeadingPairs><TitlesOfParts><vt:vector size="1" baseType="lpstr"><vt:lpstr></vt:lpstr></vt:vector></TitlesOfParts><Company></Company><LinksUpToDate>false</LinksUpToDate><CharactersWithSpaces>0</CharactersWithSpaces><SharedDoc>false</SharedDoc><HyperlinksChanged>false</HyperlinksChanged><AppVersion>16.0000</AppVersion></Properties>';	}	//Fichier docProps/core.xml	public static function core(){		global $myUser;		return '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><dc:title></dc:title><dc:subject></dc:subject><dc:creator>'.$myUser->fullName().'</dc:creator><cp:keywords></cp:keywords><cp:lastModifiedBy>'.$myUser->fullName().'</cp:lastModifiedBy><cp:revision>1</cp:revision><dcterms:created xsi:type="dcterms:W3CDTF">'.date('Y-m-d').'T'.date('H:i:s').'Z'.'</dcterms:created><dcterms:modified xsi:type="dcterms:W3CDTF">'.date('Y-m-d').'T'.date('H:i:s').'Z'.'</dcterms:modified></cp:coreProperties>';	}	/** _RELS **/	//Fichier _rels/.rels	public static function single_rels(){		return '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>';	}	/** WORD **/	//Fichier word/_rels/document.xml.rels	public static function word_rels(){		return '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings" Target="webSettings.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings" Target="settings.xml"/><Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable" Target="fontTable.xml"/></Relationships>';	}	//Fichier word/webSettings.xml	public static function web_settings(){		return '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><w:webSettings xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" mc:Ignorable="w14 w15 w16se w16cid"><w:optimizeForBrowser/><w:allowPNG/></w:webSettings>';	}	//Fichier word/settings.xml	public static function settings(){		return '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><w:settings xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" xmlns:sl="http://schemas.openxmlformats.org/schemaLibrary/2006/main" mc:Ignorable="w14 w15 w16se w16cid"><w:zoom w:percent="100"/><w:proofState w:spelling="clean" w:grammar="clean"/><w:defaultTabStop w:val="708"/><w:hyphenationZone w:val="425"/><w:characterSpacingControl w:val="doNotCompress"/><w:compat><w:compatSetting w:name="compatibilityMode" w:uri="http://schemas.microsoft.com/office/word" w:val="15"/><w:compatSetting w:name="overrideTableStyleFontSizeAndJustification" w:uri="http://schemas.microsoft.com/office/word" w:val="1"/><w:compatSetting w:name="enableOpenTypeFeatures" w:uri="http://schemas.microsoft.com/office/word" w:val="1"/><w:compatSetting w:name="doNotFlipMirrorIndents" w:uri="http://schemas.microsoft.com/office/word" w:val="1"/><w:compatSetting w:name="differentiateMultirowTableHeaders" w:uri="http://schemas.microsoft.com/office/word" w:val="1"/><w:compatSetting w:name="useWord2013TrackBottomHyphenation" w:uri="http://schemas.microsoft.com/office/word" w:val="0"/></w:compat><m:mathPr><m:mathFont m:val="Cambria Math"/><m:brkBin m:val="before"/><m:brkBinSub m:val="--"/><m:smallFrac m:val="0"/><m:dispDef/><m:lMargin m:val="0"/><m:rMargin m:val="0"/><m:defJc m:val="centerGroup"/><m:wrapIndent m:val="1440"/><m:intLim m:val="subSup"/><m:naryLim m:val="undOvr"/></m:mathPr><w:themeFontLang w:val="fr-FR"/><w:clrSchemeMapping w:bg1="light1" w:t1="dark1" w:bg2="light2" w:t2="dark2" w:accent1="accent1" w:accent2="accent2" w:accent3="accent3" w:accent4="accent4" w:accent5="accent5" w:accent6="accent6" w:hyperlink="hyperlink" w:followedHyperlink="followedHyperlink"/><w:shapeDefaults><o:shapedefaults v:ext="edit" spidmax="1026"/><o:shapelayout v:ext="edit"><o:idmap v:ext="edit" data="1"/></o:shapelayout></w:shapeDefaults><w:decimalSymbol w:val=","/><w:listSeparator w:val=";"/><w15:chartTrackingRefBased/><w15:docId w15:val="{E4CFD658-C7F9-47A9-A972-9FA0C777DED5}"/></w:settings>';	}	//Fichier word/fontTable.xml	public static function font_table(){		return '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><w:fonts xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" mc:Ignorable="w14 w15 w16se w16cid"><w:font w:name="Calibri"><w:panose1 w:val="020F0502020204030204"/><w:charset w:val="00"/><w:family w:val="swiss"/><w:pitch w:val="variable"/><w:sig w:usb0="E0002AFF" w:usb1="4000ACFF" w:usb2="00000001" w:usb3="00000000" w:csb0="000001FF" w:csb1="00000000"/></w:font></w:fonts>';	}	//créée le document d'exemple	public static function document($rows){		$stream = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><w:document xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex" xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex" xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex" xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex" xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex" xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex" xmlns:cx6="http://schemas.microsoft.com/office/drawing/2016/5/12/chartex" xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5/13/chartex" xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:aink="http://schemas.microsoft.com/office/drawing/2016/ink" xmlns:am3d="http://schemas.microsoft.com/office/drawing/2017/model3d" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 w16se w16cid wp14"><w:body>';		foreach($rows as $row){			$stream .= '<w:p><w:r>';			if(isset($row['style'])) {				$stream .= '<w:rPr>';				foreach ($row['style'] as $property => $value) {					$stream .= self::custom_style_map($property, $value);				}				$stream .= '</w:rPr>';			}			$stream .= '<w:t>'. htmlspecialchars($row['content'], ENT_COMPAT).'</w:t>';			$stream .= '</w:r></w:p>';		}		$stream .= '<w:sectPr><w:pgSz w:w="11906" w:h="16838"/><w:pgMar w:top="720" w:right="720" w:bottom="720" w:left="720" w:header="708" w:footer="708" w:gutter="0"/><w:cols w:space="708"/><w:docGrid w:linePitch="360"/></w:sectPr></w:body></w:document>';		return $stream;	}	//Retourne les différentes balises de style	public static function custom_style_map($property=null, $value=null){		$stdFontSize = 22; //11pt * 2		$stdColor = '000000';		$stdHighlight = 'none';		$stdHighlightColors= array('black','blue','cyan','green','magenta','red','yellow','white','darkBlue','darkCyan','darkGreen','darkMagenta','darkRed','darkYellow','darkGray','lightGray');		$basic = array(			'bold' => array('tag'=>'<w:b/>'),			'italic' => array('tag'=>'<w:i/>'),			'underline' => array('tag'=>'<w:u w:val="single"/>'),			'strike' => array('tag'=>'<w:strike/>'),			'caps' => array('tag'=>'<w:caps/>'),		);		if(isset($value)){			$advanced =	array(				'font-size' => array('tag'=>'<w:sz w:val="'.(is_numeric($value)?$value*2:22).'"/>'),				'color' => array('tag'=>'<w:color w:val="'.(ctype_xdigit($value) && strlen($value)==6)?ltrim($value,'#'):$stdColor.'"/>'),				'highlight' => array('tag'=>'<w:highlight w:val="'.(in_array($value,$stdHighlightColors))?$value:$stdHighlight.'"/>')			);		}		$styles = array_merge($basic, $advanced);		return isset($property) && isset($styles[$property]) ? $styles[$property]['tag'] : '';	}	//Crée un fichier Word (format .docx) au chemin	//$path indiqué avec les données $rows fournies	//en paramètres	/** Tableau de données attendu :	 *	$rows = array(	 *		0 => array(	 *			'content' => 'Macros disponibles :',	 *			'style' => array(	 *				'bold' => true,	 *				'font-size' => 16	 *			)	 *		),	 *		1 => array(	 *			'content' => '[programme.date]'	 *		),	 *		2 => array(	 *			'content' => '[programme.heure]'	 *		)	 *	);	 *	 * Chaque entrée dans $rows correspond à une ligne (paragraphe) sur le fichier	 **/	public static function write($path, $rows){		$docx = new ZipArchive();		if(file_exists($path)) unlink($path);		$docx->open($path, ZipArchive::CREATE);		//root		$docx->addFromString('[Content_Types].xml', self::content_types());		//_rels folder		$docx->addFromString('_rels/.rels', self::single_rels());		//docProps folder		$docx->addFromString('docProps/app.xml', self::app());		$docx->addFromString('docProps/core.xml', self::core());		//word folder		$docx->addFromString('word/_rels/document.xml.rels', self::word_rels());		$docx->addFromString('word/document.xml', self::document($rows));		$docx->addFromString('word/fontTable.xml', self::font_table());		$docx->addFromString('word/settings.xml', self::settings());		$docx->addFromString('word/webSettings.xml', self::web_settings());		$docx->close();	}	public function parse($filePath){		$this->zip = new ZipArchive();		$res = $this->zip->open($filePath);		if($res !== TRUE)  throw new Exception('Impossible d\'ouvrir le ZIP, code:' . $res);		$this->body = self::strip($this->zip->getFromName('word/document.xml'));		$this->footer = self::strip($this->zip->getFromName('word/footer1.xml'));		$this->header = self::strip($this->zip->getFromName('word/header1.xml'));		$this->relationships = $this->zip->getFromName('word/_rels/document.xml.rels');	}	public function add_image($tag, $img, $return=false){		//Unité utilisé en OOXML, 1px = 9525 EMU		$emu = 9525;		$pathParts = explode(SLASH, $img);		$imgParts = explode('.', end($pathParts));		preg_match('/(jpg|jpeg|png|gif)/', end($imgParts), $ext);		$ext = $ext[0];		$imgParts[array_search(end($imgParts), $imgParts)] = $ext;		$cType = in_array($ext, array('jpg', 'jpeg')) ? 'jpeg' : $ext;		$pathParts[array_search(end($pathParts), $pathParts)] = implode('.', $imgParts);		$imgUrl = implode(SLASH, $pathParts);		$img = strpos($imgUrl, __ROOT__) !== false ? $img : __ROOT__.$imgUrl;		//Récupération taille image		list($width, $height) = getimagesize($img);		$mimeTypes = $this->zip->getFromName('[Content_Types].xml', 0, ZipArchive::OVERWRITE);		if(strrpos($mimeTypes, '<Default Extension="'.$ext.'" ContentType="image/'.$cType.'"/>') === false) {			$mimeTypes = str_replace('</Types>', '<Default Extension="gif" ContentType="image/gif"/><Default Extension="png" ContentType="image/png"/><Default Extension="jpeg" ContentType="image/jpeg"/><Default Extension="jpg" ContentType="image/jpeg"/></Types>', $mimeTypes);			// $mimeTypes = str_replace('</Types>', '<Default Extension="'.$ext.'" ContentType="image/'.$cType.'"/></Types>', $mimeTypes);			$this->zip->addFromString('[Content_Types].xml', $mimeTypes);		}		$i = 100;		$uid = 'img'.$i;		while(strpos($this->relationships, 'Id="'.$uid.'"') !== false){			$i++;			$uid = 'img'.$i;		}		$this->zip->addFile($img, 'word/media/'.$uid.'.'.$ext);		$rel = '<Relationship Id="'.$uid.'" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/'.$uid.'.'.$ext.'"/>';		$this->relationships = str_replace('</Relationships>',$rel.'</Relationships>',$this->relationships);		$xmlPic = '<w:drawing><wp:inline distT="0" distB="0" distL="0" distR="0" ><wp:extent cx="'.$width*$emu.'" cy="'.$height*$emu.'"/><wp:effectExtent l="1" t="1" r="1" b="1"/><wp:docPr id="'.rand(100,200).'" name="'.$uid.'" descr=""/><wp:cNvGraphicFramePr><a:graphicFrameLocks xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" noChangeAspect="1"/></wp:cNvGraphicFramePr><a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"><a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture"><pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture"><pic:nvPicPr><pic:cNvPr id="0" name=""/><pic:cNvPicPr/></pic:nvPicPr><pic:blipFill><a:blip r:embed="'.$uid.'"/><a:stretch><a:fillRect/></a:stretch></pic:blipFill><pic:spPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="'.$width*$emu.'" cy="'.$height*$emu.'"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></pic:spPr></pic:pic></a:graphicData></a:graphic></wp:inline></w:drawing>';		$this->body = str_replace('{{'.$tag.'}}',$xmlPic, $this->body);		if($return){			$datas['picture'] = $xmlPic;			$datas['cType'] = $mimeTypes;			return $datas;		}	}	//crée le document final avec les tags remplacés	public static function from_template($source, $data, $return){ 		$destination = File::dir().'tmp'.SLASH.'template.'.time().'-'.rand(0,100).'.docx';		$source = File::dir().$source;		copy($source,$destination);		$docx = new self();		$docx->parse($destination);		foreach($data as $tag => $value){ 			if(is_array($value)){				$docx->body = preg_replace_callback('#\{\{\#'.$tag.'\}\}(.*)\{\{\/'.$tag.'\}\}#si', function ($match) use($value, $docx) {					$content = '';					foreach($value as $line){						$bloc = $match[1];						foreach($line as $subTag=>$subValue){							if(substr($subValue,0,2)=='::' && strpos($bloc, '{{'.$subTag.'}}') !== false) {								$picDatas = $docx->add_image($subTag, substr($subValue,2), true);								$bloc = str_replace('{{'.$subTag.'}}',$picDatas['picture'],$bloc);								continue;							}							$subValue = self::convert_text_format($subValue);							$bloc = str_replace('{{'.$subTag.'}}',$subValue,$bloc);						}						$content .=$bloc;					}					return $content;				},$docx->body);				continue;			}			if(substr($value,0,2)=='::'){				$docx->add_image($tag, substr($value,2));				continue;			}			$value = self::convert_text_format($value);			$docx->body = str_replace('{{'.$tag.'}}',$value,$docx->body);			$docx->footer = str_replace('{{'.$tag.'}}',$value,$docx->footer);			$docx->header = str_replace('{{'.$tag.'}}',$value,$docx->header);		}			//conditions - if		$ifRegex = '/\{\{\#([^\/\:\#}]*)\}\}(.*?)\{\{\/\1\}\}/is';		$docx->body = preg_replace_callback($ifRegex,function($matches) use ($data) {			$key = $matches[1];			$docx->body = $matches[2];			return !isset($data[$key]) || (!is_array($data[$key]) && empty($data[$key])) || (is_array($data[$key]) && count($data[$key])==0) ?'':$docx->body;		},$docx->body);				//conditions - else		$elseRegex = '/\{\{\^([^\/\:\#}]*)\}\}(.*?)\{\{\/\1\}\}/is';		$docx->body = preg_replace_callback($elseRegex,function($matches) use ($data) {			$key = $matches[1];			$docx->body = $matches[2];			return (isset($data[$key]) && !is_array($data[$key]) && !empty($data[$key])) || (is_array($data[$key]) && count($data[$key])>0) ?'':$docx->body;		},$docx->body);		$docx->save();		$docx->close();		if($return!='stream') return $destination;		$stream = file_get_contents($destination);		unlink($destination);		return $stream;	}	public static function convert_text_format($value){		//Remplace les <p> et les <br> par les w:br word		$value = str_replace(array('<br>','<p>','</p>','<ul>'),'<w:br/>',$value);		//todo ameliorable		$value = str_replace(array('<li>'),' - ',$value);		$value = str_replace(array('</li>'),'<w:br/>',$value);		$value = str_replace('</ul>','',$value);		        //todo - $value = preg_replace('|<strong>([^<]*)</strong>|is', '<w:r w:rsidRPr="00556DA8"><w:rPr><w:b /></w:rPr><w:t>$1</w:t></w:r>', $value);				//Remplace les & par des &		$value = str_replace(array('&'), array('&'), $value);		//remplace les balises non word (ne commencant pas par <w: ou </w: )		$value = preg_replace('|<(?!/?w:)([^>]*)>|is', '<$1>', $value);		return $value;	}	//Ajoute au fichier les différentes modifications effectuées	public function save(){		$this->zip->addFromString('word/document.xml', $this->body);		if(!empty($this->header)) $this->zip->addFromString('word/header1.xml', $this->header);		if(!empty($this->footer)) $this->zip->addFromString('word/footer1.xml', $this->footer);		$this->zip->addFromString('word/_rels/document.xml.rels', $this->relationships);	}	//Ferme le fichier	public function close(){		$this->zip->close();	}	public static function strip($content){		$content = preg_replace_callback(			'#\{\{([^\]]+)\}\}#U',			function ($match) {				return strip_tags($match[0]);			},			$content		);		return $content;	}}?>
 |