From 9dd4ed9cb8e9c5564efd43b3cbe7f32e3b8d94eb Mon Sep 17 00:00:00 2001 From: fhenry <florian.henry@open-concept.pro> Date: Mon, 25 Mar 2013 19:28:34 +0100 Subject: [PATCH] [ task #770 ] Add ODT document generation for Projects module --- .../doctemplates/project/template_project.odt | Bin 0 -> 25790 bytes .../project/template_task_summary.odt | Bin 0 -> 15625 bytes htdocs/admin/project.php | 187 ++++--- htdocs/core/modules/modProjet.class.php | 7 + .../pdf/doc_generic_project_odt.modules.php | 481 ++++++++++++++++++ htdocs/projet/class/project.class.php | 3 +- 6 files changed, 594 insertions(+), 84 deletions(-) create mode 100755 documents/doctemplates/project/template_project.odt create mode 100755 documents/doctemplates/project/template_task_summary.odt create mode 100644 htdocs/core/modules/project/pdf/doc_generic_project_odt.modules.php diff --git a/documents/doctemplates/project/template_project.odt b/documents/doctemplates/project/template_project.odt new file mode 100755 index 0000000000000000000000000000000000000000..fcf5f52d80126f4af6bd2ecb629f5721a5b606f1 GIT binary patch literal 25790 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 literal 0 HcmV?d00001 diff --git a/documents/doctemplates/project/template_task_summary.odt b/documents/doctemplates/project/template_task_summary.odt new file mode 100755 index 0000000000000000000000000000000000000000..67c43a785d2dbac54867ce9f13a7565ed4acdeac GIT binary patch literal 15625 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˿{+_57Lfn+<>TJ&@C5RY6V`0OB9@b22iv2GRrU zoNb->NguoKk3<U_BeVaJXlMLn(ceYwf01PQUESWu(a6lv$lm;?Fw0M1S35_OpNX7Y zzl#IRALRi~K*ygs98BE5XW81>(z}{lH~~TSMu10){w~SR#zo2~@LLU?L5~O~KvN4_ zpviC5cp6Fkq*At~c8)ei0E_NwTVm$_PMqbx6KDPJ#Mz$2e;*D!PYwU)+aI6nNAkb> zS)P`bHb%A<ra+JrgQJP*aNMwMAQS5A1HK^O$ea)(6qF<NK%-?=2Yaw46ytF!`bt|= zoVrq8@lMv%m$Fx^t5G#+dq()5!mElpRoMVE6a$jxwcB(&%?yqCi#!W+b#z3j1V@&E z`B}70uC}z?28luRoQT$=)$gd?Qcw64T1Y#mxf~=BduyU#;Rqu|EY7}qz2F{Mhcnes za{8Vf<9<QRAHK}<KD!Fus7|>xq>eb&UnmkzcHp&BAbyj)Ob=_~i4u2b&fa>TVe4ez zJ3hlhx~S2)l{bh58~UGHEB18*SG^L<J@x?}&XYYyt7P$p=`8ySJI%cA4_o&PqYt?2 z<uxv1)<Pq>X4f%WHOEA166H^1UUOkS0rd<FED+-FWd7J<e}os0F;P2PQwy`-834q> zXm4llZ2!oJ&WwM(t@MY|V}$4*^nMH)5Tl5NlZ}x*=szgq|AX@5csFwdf<VSbj{iaP z>5|mn&2_S~v;NOo|5V8*Eqfzdp!I)QnyIzjBe(vyHa@lHpEmxJ@A2tA+23ns1OPnF zO+Sc}5#a3T_`5F=;)fgZQ6B8+`qxwV_wV#iRevHt=U*E7pUlB}M3oa)6{eSxf5rI6 z_<EdiOI2lTyNOYkFEF1k4vd+q<#1`K?!Zkz$R5rK2XqFIgxMM3vu71cV||z(zG&@3 ztk5ND`EZUChcxv@<BF7)979{in@oU{=qydMJTsB-lS{H@Rz&fs5>IpFr&uRHlQ_!5 zWHvkk=sb?(-B`_sl39s@YF7$F5_N^?pz><u?-N9QGR{dEA7DP~kxkLZ$jkw(ayA`0 zUUe{WS^3GNEU3^$2W-^J_q!S9Y?{yQR;{9ICShjDax40Z2A+-OrXE*o;zy8xY&v!i zqb6<Wh4HtPl7;vpvrBfMyV>yB^Uc;M2?+}Nx=BHe1<^3)pAOx|4w55mT>I{&r%$Y- zE`&1nKzt&3LEwNfBL`7c%D&4B$A>=Wt#FwXN;noBi!wCI<NWKh;gYr=UkM3<tbp!u z6y`iGoD^lAfn$RG`&GgppYo4CKQ9*kUF+|62LDh1lY5N*+YQ2>C_lgTuTJbI3jH&T zJ>Et9)d~K0&0k#)PfqSX1O8)Y`^Dw`cg0_~3Z6U@e}-)0U;Pw+*ZXx<`d3qFX#Tpb z@Kf{OR;_=Qc+T)RYdp?3PixqpT0fiSSK|C@d9PXjI@kQv{8`?g_+Vg91Mkn!&GtV> z_pdbj*N*Y0-fu+v=ljh+;QSBT{dce@;{7vlvHycnf1%-jM|vXSKZD~xApJ?p|Bmw4 zMk@Ljl%F*H?>K+8=JP+`{7KvYTa@P<|Fd=er19TSes-CsmiWoVPelG_ko^agf1&mN xeQ(PB2hd+h{jbLTN<mnETJ{)Qe8l-jl2??0dUP&69dSViD}H1yDXyot{{t_mBIW=9 literal 0 HcmV?d00001 diff --git a/htdocs/admin/project.php b/htdocs/admin/project.php index f2f216d7b52..e971eb92e51 100644 --- a/htdocs/admin/project.php +++ b/htdocs/admin/project.php @@ -1,28 +1,28 @@ <?php /* Copyright (C) 2010 Regis Houssin <regis.houssin@capnetworks.com> * Copyright (C) 2011 Laurent Destailleur <eldy@users.sourceforge.net> - * Copyright (C) 2011-2012 Juanjo Menent <jmenent@2byte.es> - * Copyright (C) 2011-2013 Philippe Grand <philippe.grand@atoo-net.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ +* Copyright (C) 2011-2012 Juanjo Menent <jmenent@2byte.es> +* Copyright (C) 2011-2013 Philippe Grand <philippe.grand@atoo-net.com> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ /** * \file htdocs/admin/project.php * \ingroup project * \brief Page to setup project module - */ +*/ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; @@ -45,7 +45,7 @@ $type='project'; /* * Actions - */ +*/ if ($action == 'updateMask') { @@ -56,14 +56,14 @@ if ($action == 'updateMask') if (! $res > 0) $error++; - if (! $error) - { - $mesg = "<font class=\"ok\">".$langs->trans("SetupSaved")."</font>"; - } - else - { - $mesg = "<font class=\"error\">".$langs->trans("Error")."</font>"; - } + if (! $error) + { + $mesg = "<font class=\"ok\">".$langs->trans("SetupSaved")."</font>"; + } + else + { + $mesg = "<font class=\"error\">".$langs->trans("Error")."</font>"; + } } else if ($action == 'specimen') @@ -78,7 +78,7 @@ else if ($action == 'specimen') $dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']); foreach($dirmodels as $reldir) { - $file=dol_buildpath($reldir."core/modules/project/pdf/pdf_".$modele.".modules.php",0); + $file=dol_buildpath($reldir."core/modules/project/pdf/pdf_".$modele.".modules.php",0); if (file_exists($file)) { $filefound=1; @@ -95,8 +95,8 @@ else if ($action == 'specimen') if ($module->write_file($project,$langs) > 0) { - header("Location: ".DOL_URL_ROOT."/document.php?modulepart=project&file=SPECIMEN.pdf"); - return; + header("Location: ".DOL_URL_ROOT."/document.php?modulepart=project&file=SPECIMEN.pdf"); + return; } else { @@ -122,7 +122,7 @@ else if ($action == 'del') $ret = delDocumentModel($value, $type); if ($ret > 0) { - if ($conf->global->PROJECT_ADDON_PDF == "$value") dolibarr_del_const($db, 'PROJECT_ADDON_PDF',$conf->entity); + if ($conf->global->PROJECT_ADDON_PDF == "$value") dolibarr_del_const($db, 'PROJECT_ADDON_PDF',$conf->entity); } } @@ -154,7 +154,7 @@ else if ($action == 'setmod') /* * View - */ +*/ $dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']); @@ -179,8 +179,8 @@ dol_fiche_head($head, $hselected, $langs->trans("ModuleSetup")); /* * Projects Numbering model - */ - +*/ + print_titre($langs->trans("ProjectsNumberingModules")); print '<table class="noborder" width="100%">'; @@ -284,7 +284,7 @@ print '</table><br>'; /* * Document templates generators - */ +*/ print_titre($langs->trans("ProjectsModelModule")); @@ -337,59 +337,80 @@ foreach ($dirmodels as $reldir) { while (($file = readdir($handle))!==false) { - if (substr($file, dol_strlen($file) -12) == '.modules.php' && substr($file,0,4) == 'pdf_') + if (preg_match('/\.modules\.php$/i',$file) && preg_match('/^(pdf_|doc_)/',$file)) { - $name = substr($file, 4, dol_strlen($file) -16); - $classname = substr($file, 0, dol_strlen($file) -12); - - $var=!$var; - print "<tr ".$bc[$var].">\n <td>$name"; - print "</td>\n <td>\n"; - require_once $dir.$file; - $module = new $classname($db); - print $module->description; - print "</td>\n"; - - // Active - if (in_array($name, $def)) - { - print "<td align=\"center\">\n"; - print '<a href="'.$_SERVER["PHP_SELF"].'?action=del&value='.$name.'&scandir='.$module->scandir.'&label='.urlencode($module->name).'">'; - print img_picto($langs->trans("Enabled"),'switch_on'); - print '</a>'; - print "</td>"; - } - else + if (file_exists($dir.'/'.$file)) { - print "<td align=\"center\">\n"; - print '<a href="'.$_SERVER["PHP_SELF"].'?action=set&value='.$name.'&scandir='.$module->scandir.'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"),'switch_off').'</a>'; - print "</td>"; - } + $name = substr($file, 4, dol_strlen($file) -16); + $classname = substr($file, 0, dol_strlen($file) -12); - // Default - print "<td align=\"center\">"; - if ($conf->global->PROJECT_ADDON_PDF == "$name") - { - print img_picto($langs->trans("Default"),'on'); - } - else - { - print '<a href="'.$_SERVER["PHP_SELF"].'?action=setdoc&value='.$name.'&scandir='.$module->scandir.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"),'off').'</a>'; + require_once $dir.'/'.$file; + $module = new $classname($db); + + $modulequalified=1; + if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) $modulequalified=0; + if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) $modulequalified=0; + + if ($modulequalified) + { + $var=!$var; + print '<tr '.$bc[$var].'><td width="100">'; + print (empty($module->name)?$name:$module->name); + print "</td><td>\n"; + if (method_exists($module,'info')) print $module->info($langs); + else print $module->description; + print "</td>\n"; + + // Active + if (in_array($name, $def)) + { + print "<td align=\"center\">\n"; + print '<a href="'.$_SERVER["PHP_SELF"].'?action=del&value='.$name.'&scandir='.$module->scandir.'&label='.urlencode($module->name).'">'; + print img_picto($langs->trans("Enabled"),'switch_on'); + print '</a>'; + print "</td>"; + } + else + { + print "<td align=\"center\">\n"; + print '<a href="'.$_SERVER["PHP_SELF"].'?action=set&value='.$name.'&scandir='.$module->scandir.'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"),'switch_off').'</a>'; + print "</td>"; + } + + // Default + print "<td align=\"center\">"; + if ($conf->global->PROJECT_ADDON_PDF == "$name") + { + print img_picto($langs->trans("Default"),'on'); + } + else + { + print '<a href="'.$_SERVER["PHP_SELF"].'?action=setdoc&value='.$name.'&scandir='.$module->scandir.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"),'off').'</a>'; + } + print '</td>'; + + // Info + $htmltooltip = ''.$langs->trans("Name").': '.$module->name; + $htmltooltip.='<br>'.$langs->trans("Type").': '.($module->type?$module->type:$langs->trans("Unknown")); + $htmltooltip.='<br>'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur; + $htmltooltip.='<br><br><u>'.$langs->trans("FeaturesSupported").':</u>'; + $htmltooltip.='<br>'.$langs->trans("Logo").': '.yn($module->option_logo,1,1); + + // Preview + print '<td align="center">'; + if ($module->type == 'pdf') + { + print '<a href="'.$_SERVER["PHP_SELF"].'?action=specimen&module='.$name.'">'.img_object($langs->trans("Preview"),'bill').'</a>'; + } + else + { + print img_object($langs->trans("PreviewNotAvailable"),'generic'); + } + print '</td>'; + + print "</tr>\n"; + } } - print '</td>'; - - // Info - $htmltooltip = ''.$langs->trans("Name").': '.$module->name; - $htmltooltip.='<br>'.$langs->trans("Type").': '.($module->type?$module->type:$langs->trans("Unknown")); - $htmltooltip.='<br>'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur; - $htmltooltip.='<br><br><u>'.$langs->trans("FeaturesSupported").':</u>'; - $htmltooltip.='<br>'.$langs->trans("Logo").': '.yn($module->option_logo,1,1); - print '<td align="center">'; - $link='<a href="'.$_SERVER["PHP_SELF"].'?action=specimen&module='.$name.'">'.img_object($langs->trans("Preview"),'project').'</a>'; - print $form->textwithpicto(' '.$link,$htmltooltip,-1,0); - print '</td>'; - - print "</tr>\n"; } } closedir($handle); diff --git a/htdocs/core/modules/modProjet.class.php b/htdocs/core/modules/modProjet.class.php index 877bea83b22..a17835ddcc6 100644 --- a/htdocs/core/modules/modProjet.class.php +++ b/htdocs/core/modules/modProjet.class.php @@ -86,6 +86,13 @@ class modProjet extends DolibarrModules $this->const[$r][4] = 0; $r++; + $r++; + $this->const[$r][0] = "PROJECT_ADDON_PDF_ODT_PATH"; + $this->const[$r][1] = "chaine"; + $this->const[$r][2] = "DOL_DATA_ROOT/doctemplates/project"; + $this->const[$r][3] = ""; + $this->const[$r][4] = 0; + // Boxes $this->boxes = array(); diff --git a/htdocs/core/modules/project/pdf/doc_generic_project_odt.modules.php b/htdocs/core/modules/project/pdf/doc_generic_project_odt.modules.php new file mode 100644 index 00000000000..7ba6defaa3b --- /dev/null +++ b/htdocs/core/modules/project/pdf/doc_generic_project_odt.modules.php @@ -0,0 +1,481 @@ +<?php +/* Copyright (C) 2010-2012 Laurent Destailleur <eldy@users.sourceforge.net> + * Copyright (C) 2012 Juanjo Menent <jmenent@2byte.es> + * Copyright (C) 2013 Florian Henry <florian.henry@ope-concept.pro> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * or see http://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php + * \ingroup commande + * \brief File of class to build ODT documents for third parties + */ + +require_once DOL_DOCUMENT_ROOT.'/core/modules/project/modules_project.php'; +require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; +require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/doc.lib.php'; + + +/** + * Class to build documents using ODF templates generator + */ +class doc_generic_project_odt extends ModelePDFProjects +{ + var $emetteur; // Objet societe qui emet + + var $phpmin = array(5,2,0); // Minimum version of PHP required by module + var $version = 'dolibarr'; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + global $conf,$langs,$mysoc; + + $langs->load("main"); + $langs->load("companies"); + + $this->db = $db; + $this->name = "ODT templates"; + $this->description = $langs->trans("DocumentModelOdt"); + $this->scandir = 'PROJECT_ADDON_PDF_ODT_PATH'; // Name of constant that is used to save list of directories to scan + + // Dimension page pour format A4 + $this->type = 'odt'; + $this->page_largeur = 0; + $this->page_hauteur = 0; + $this->format = array($this->page_largeur,$this->page_hauteur); + $this->marge_gauche=0; + $this->marge_droite=0; + $this->marge_haute=0; + $this->marge_basse=0; + + $this->option_logo = 1; // Affiche logo + $this->option_tva = 0; // Gere option tva COMMANDE_TVAOPTION + $this->option_modereg = 0; // Affiche mode reglement + $this->option_condreg = 0; // Affiche conditions reglement + $this->option_codeproduitservice = 0; // Affiche code produit-service + $this->option_multilang = 0; // Dispo en plusieurs langues + $this->option_escompte = 0; // Affiche si il y a eu escompte + $this->option_credit_note = 0; // Support credit notes + $this->option_freetext = 1; // Support add of a personalised text + $this->option_draft_watermark = 0; // Support add of a watermark on drafts + + // Recupere emetteur + $this->emetteur=$mysoc; + if (! $this->emetteur->pays_code) $this->emetteur->pays_code=substr($langs->defaultlang,-2); // Par defaut, si n'etait pas defini + } + + + /** + * Define array with couple substitution key => substitution value + * + * @param Object $object Main object to use as data source + * @param Translate $outputlangs Lang object to use for output + * @return array Array of substitution + */ + function get_substitutionarray_object($object,$outputlangs) + { + global $conf; + dol_syslog(get_class($this)."::get_substitutionarray_object object=".var_export($object,true), LOG_DEBUG); + return array( + 'object_id'=>$object->id, + 'object_ref'=>$object->ref, + 'object_title'=>$object->title, + 'object_description'=>$object->description, + 'object_date_creation'=>dol_print_date($object->date_c,'day'), + 'object_date_modification'=>dol_print_date($object->date_m,'day'), + 'object_date_start'=>dol_print_date($object->date_start,'day'), + 'object_date_end'=>dol_print_date($object->date_end,'day'), + 'object_note_private'=>$object->note_private, + 'object_note_public'=>$object->note_public, + 'object_public'=>$object->public, + 'object_statut'=>$object->getLibStatut() + ); + } + + /** + * Define array with couple substitution key => substitution value + * + * @param array $line Array of lines + * @param Translate $outputlangs Lang object to use for output + * @return array Return a substitution array + */ + function get_substitutionarray_lines($line,$outputlangs) + { + global $conf; + + return array( + 'line_ref'=>$line->ref, + 'line_fk_project'=>$line->fk_project, + 'line_projectref'=>$line->projectref, + 'line_projectlabel'=>$line->projectlabel, + 'line_label'=>$line->label, + 'line_description'=>$line->description, + 'line_fk_parent'=>$line->fk_parent, + 'line_duration'=>$line->duration, + 'line_progress'=>$line->progress, + 'line_public'=>$line->public, + 'line_date_start'=>dol_print_date($line->date_start,'day'), + 'line_date_end'=>dol_print_date($line->date_end,'day') + ); + } + + /** + * Return description of a module + * + * @param Translate $langs Lang object to use for output + * @return string Description + */ + function info($langs) + { + global $conf,$langs; + + $langs->load("companies"); + $langs->load("errors"); + + $form = new Form($this->db); + + $texte = $this->description.".<br>\n"; + $texte.= '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">'; + $texte.= '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + $texte.= '<input type="hidden" name="action" value="setModuleOptions">'; + $texte.= '<input type="hidden" name="param1" value="PROJECT_ADDON_PDF_ODT_PATH">'; + $texte.= '<table class="nobordernopadding" width="100%">'; + + // List of directories area + $texte.= '<tr><td>'; + $texttitle=$langs->trans("ListOfDirectories"); + $listofdir=explode(',',preg_replace('/[\r\n]+/',',',trim($conf->global->PROJECT_ADDON_PDF_ODT_PATH))); + $listoffiles=array(); + foreach($listofdir as $key=>$tmpdir) + { + $tmpdir=trim($tmpdir); + $tmpdir=preg_replace('/DOL_DATA_ROOT/',DOL_DATA_ROOT,$tmpdir); + if (! $tmpdir) { unset($listofdir[$key]); continue; } + if (! is_dir($tmpdir)) $texttitle.=img_warning($langs->trans("ErrorDirNotFound",$tmpdir),0); + else + { + $tmpfiles=dol_dir_list($tmpdir,'files',0,'\.odt'); + if (count($tmpfiles)) $listoffiles=array_merge($listoffiles,$tmpfiles); + } + } + $texthelp=$langs->trans("ListOfDirectoriesForModelGenODT"); + // Add list of substitution keys + $texthelp.='<br>'.$langs->trans("FollowingSubstitutionKeysCanBeUsed").'<br>'; + $texthelp.=$langs->transnoentitiesnoconv("FullListOnOnlineDocumentation"); // This contains an url, we don't modify it + + $texte.= $form->textwithpicto($texttitle,$texthelp,1,'help','',1); + $texte.= '<table><tr><td>'; + $texte.= '<textarea class="flat" cols="60" name="value1">'; + $texte.=$conf->global->PROJECT_ADDON_PDF_ODT_PATH; + $texte.= '</textarea>'; + $texte.= '</td>'; + $texte.= '<td align="center"> '; + $texte.= '<input type="submit" class="button" value="'.$langs->trans("Modify").'" name="Button">'; + $texte.= '</td>'; + $texte.= '</tr>'; + $texte.= '</table>'; + + // Scan directories + if (count($listofdir)) $texte.=$langs->trans("NumberOfModelFilesFound").': <b>'.count($listoffiles).'</b>'; + + $texte.= '</td>'; + + + $texte.= '<td valign="top" rowspan="2">'; + $texte.= $langs->trans("ExampleOfDirectoriesForModelGen"); + $texte.= '</td>'; + $texte.= '</tr>'; + + /*$texte.= '<tr>'; + $texte.= '<td align="center">'; + $texte.= '<input type="submit" class="button" value="'.$langs->trans("Modify").'" name="Button">'; + $texte.= '</td>'; + $texte.= '</tr>';*/ + + $texte.= '</table>'; + $texte.= '</form>'; + + return $texte; + } + + /** + * Function to build a document on disk using the generic odt module. + * + * @param Commande $object Object source to build document + * @param Translate $outputlangs Lang output object + * @param string $srctemplatepath Full path of source filename for generator using a template file + * @return int 1 if OK, <=0 if KO + */ + function write_file($object,$outputlangs,$srctemplatepath) + { + global $user,$langs,$conf,$mysoc; + + if (empty($srctemplatepath)) + { + dol_syslog("doc_generic_odt::write_file parameter srctemplatepath empty", LOG_WARNING); + return -1; + } + + if (! is_object($outputlangs)) $outputlangs=$langs; + $sav_charset_output=$outputlangs->charset_output; + $outputlangs->charset_output='UTF-8'; + + $outputlangs->load("main"); + $outputlangs->load("dict"); + $outputlangs->load("companies"); + $outputlangs->load("projects"); + + if ($conf->projet->dir_output) + { + // If $object is id instead of object + if (! is_object($object)) + { + $id = $object; + $object = new Project($this->db); + $result=$object->fetch($id); + if ($result < 0) + { + dol_print_error($this->db,$object->error); + return -1; + } + } + + $dir = $conf->projet->dir_output; + $objectref = dol_sanitizeFileName($object->ref); + if (! preg_match('/specimen/i',$objectref)) $dir.= "/" . $objectref; + $file = $dir . "/" . $objectref . ".odt"; + + if (! file_exists($dir)) + { + if (dol_mkdir($dir) < 0) + { + $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); + return -1; + } + } + + if (file_exists($dir)) + { + //print "srctemplatepath=".$srctemplatepath; // Src filename + $newfile=basename($srctemplatepath); + $newfiletmp=preg_replace('/\.odt/i','',$newfile); + $newfiletmp=preg_replace('/template_/i','',$newfiletmp); + $newfiletmp=preg_replace('/modele_/i','',$newfiletmp); + $newfiletmp=$objectref.'_'.$newfiletmp; + //$file=$dir.'/'.$newfiletmp.'.'.dol_print_date(dol_now(),'%Y%m%d%H%M%S').'.odt'; + $file=$dir.'/'.$newfiletmp.'.odt'; + //print "newdir=".$dir; + //print "newfile=".$newfile; + //print "file=".$file; + //print "conf->societe->dir_temp=".$conf->societe->dir_temp; + + dol_mkdir($conf->projet->dir_temp); + + + // List of all contact + $usecontact=false; + $arrayidcontact=$object->liste_contact(-1,'internal'); + if (count($arrayidcontact) > 0) + { + $usecontact=true; + $result=$object->fetch_contact($arrayidcontact[0]['id']); + } + + $socobject=$object->thirdparty; + + // Make substitution + $substitutionarray=array( + '__FROM_NAME__' => $this->emetteur->nom, + '__FROM_EMAIL__' => $this->emetteur->email, + ); + complete_substitutions_array($substitutionarray, $langs, $object); + + // Open and load template + require_once ODTPHP_PATH.'odf.php'; + $odfHandler = new odf( + $srctemplatepath, + array( + 'PATH_TO_TMP' => $conf->projet->dir_temp, + 'ZIP_PROXY' => 'PclZipProxy', // PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy. + 'DELIMITER_LEFT' => '{', + 'DELIMITER_RIGHT' => '}' + ) + ); + // After construction $odfHandler->contentXml contains content and + // [!-- BEGIN row.lines --]*[!-- END row.lines --] has been replaced by + // [!-- BEGIN lines --]*[!-- END lines --] + //print html_entity_decode($odfHandler->__toString()); + //print exit; + + // Make substitutions into odt of user info + $tmparray=$this->get_substitutionarray_user($user,$outputlangs); + //var_dump($tmparray); exit; + foreach($tmparray as $key=>$value) + { + try { + if (preg_match('/logo$/',$key)) // Image + { + //var_dump($value);exit; + if (file_exists($value)) $odfHandler->setImage($key, $value); + else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); + } + else // Text + { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + } + catch(OdfException $e) + { + } + } + // Make substitutions into odt of mysoc + $tmparray=$this->get_substitutionarray_mysoc($mysoc,$outputlangs); + //var_dump($tmparray); exit; + foreach($tmparray as $key=>$value) + { + try { + if (preg_match('/logo$/',$key)) // Image + { + //var_dump($value);exit; + if (file_exists($value)) $odfHandler->setImage($key, $value); + else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); + } + else // Text + { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + } + catch(OdfException $e) + { + } + } + + // Make substitutions into odt of thirdparty + $tmparray=$this->get_substitutionarray_thirdparty($socobject,$outputlangs); + foreach($tmparray as $key=>$value) + { + try { + if (preg_match('/logo$/',$key)) // Image + { + if (file_exists($value)) $odfHandler->setImage($key, $value); + else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); + } + else // Text + { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + } + catch(OdfException $e) + { + } + } + + // Replace tags of object + external modules + $tmparray=$this->get_substitutionarray_object($object,$outputlangs); + complete_substitutions_array($tmparray, $outputlangs, $object); + foreach($tmparray as $key=>$value) + { + try { + if (preg_match('/logo$/',$key)) // Image + { + if (file_exists($value)) $odfHandler->setImage($key, $value); + else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); + } + else // Text + { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + } + catch(OdfException $e) + { + } + } + + // Replace tags of lines + try + { + $listlines = $odfHandler->setSegment('lines'); + + $taskstatic = new Task($this->db); + + // Security check + $socid=0; + if (!empty($object->fk_soc)) $socid = $object->fk_soc; + + $tasksarray=$taskstatic->getTasksArray(0, 0, $object->id, $socid, 0); + + foreach ($tasksarray as $task) + { + $tmparray=$this->get_substitutionarray_lines($task,$outputlangs); + complete_substitutions_array($tmparray, $outputlangs, $object, $task, "completesubstitutionarray_lines"); + foreach($tmparray as $key => $val) + { + try + { + $listlines->setVars($key, $val, true, 'UTF-8'); + } + catch(OdfException $e) + { + } + catch(SegmentException $e) + { + } + } + $listlines->merge(); + } + $odfHandler->mergeSegment($listlines); + } + catch(OdfException $e) + { + $this->error=$e->getMessage(); + dol_syslog($this->error, LOG_WARNING); + return -1; + } + + // Write new file + //$result=$odfHandler->exportAsAttachedFile('toto'); + $odfHandler->saveToDisk($file); + + if (! empty($conf->global->MAIN_UMASK)) + @chmod($file, octdec($conf->global->MAIN_UMASK)); + + $odfHandler=null; // Destroy object + + return 1; // Success + } + else + { + $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); + return -1; + } + } + + return -1; + } + +} + +?> diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index 97eb27745a8..226d7246e9b 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -260,7 +260,7 @@ class Project extends CommonObject if (empty($id) && empty($ref)) return -1; $sql = "SELECT rowid, ref, title, description, public, datec"; - $sql.= ", tms, dateo, datee, fk_soc, fk_user_creat, fk_statut, note_private, note_public"; + $sql.= ", tms, dateo, datee, fk_soc, fk_user_creat, fk_statut, note_private, note_public,model_pdf"; $sql.= " FROM " . MAIN_DB_PREFIX . "projet"; if (! empty($id)) { @@ -298,6 +298,7 @@ class Project extends CommonObject $this->user_author_id = $obj->fk_user_creat; $this->public = $obj->public; $this->statut = $obj->fk_statut; + $this->modelpdf = $obj->model_pdf; $this->db->free($resql); -- GitLab