From 337ebafceb8e4482e111850988d7e6e4e2c9f2c6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur <eldy@users.sourceforge.net> Date: Sun, 28 Feb 2010 22:49:06 +0000 Subject: [PATCH] Work on generic odt generation --- htdocs/admin/societe.php | 20 +++-- htdocs/compta/facture.php | 2 +- .../societe/doc/doc_generic_odt.modules.php | 69 ++++++++++------ .../modules/societe/modules_societe.class.php | 79 ++++++++++++++++++- htdocs/includes/odtphp/odf.php | 26 +++--- htdocs/langs/fr_FR/admin.lang | 2 +- htdocs/lib/functions2.lib.php | 72 ++++++++--------- htdocs/soc.php | 41 ++++++++++ 8 files changed, 230 insertions(+), 81 deletions(-) diff --git a/htdocs/admin/societe.php b/htdocs/admin/societe.php index ff0d5c4d607..9f9ae71a1f8 100644 --- a/htdocs/admin/societe.php +++ b/htdocs/admin/societe.php @@ -82,13 +82,17 @@ if ($_POST["action"] == 'setModuleOptions') { $param=$_POST["param1"]; $value=$_POST["value1"]; - dolibarr_set_const($db,$param,$value,'chaine',0,'',$conf->entity); + if ($param) dolibarr_set_const($db,$param,$value,'chaine',0,'',$conf->entity); } if ($_GET["action"] == 'set') { $type='company'; - $sql = "INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity, libelle) VALUES ('".$_GET["value"]."','".$type."',".$conf->entity.", ".($_GET["label"]?"'".addslashes($_GET["label"])."'":'null').")"; + $sql = "INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity, libelle, description)"; + $sql.= " VALUES ('".$_GET["value"]."','".$type."',".$conf->entity.", "; + $sql.= ($_GET["label"]?"'".addslashes($_GET["label"])."'":'null').", "; + $sql.= (! empty($_GET["scandir"])?"'".$_GET["scandir"]."'":"null"); + $sql.= ")"; if ($db->query($sql)) { @@ -112,7 +116,11 @@ if ($_GET["action"] == 'setdoc') $sql_del.= " AND entity = ".$conf->entity; $result1=$db->query($sql_del); - $sql = "INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity, libelle) VALUES ('".$_GET["value"]."', '".$type."', ".$conf->entity.", ".($_GET["label"]?"'".addslashes($_GET["label"])."'":'null').")"; + $sql = "INSERT INTO ".MAIN_DB_PREFIX."document_model (nom, type, entity, libelle, description)"; + $sql.= " VALUES ('".$_GET["value"]."', '".$type."', ".$conf->entity.", "; + $sql.= ($_GET["label"]?"'".addslashes($_GET["label"])."'":'null').", "; + $sql.= (! empty($_GET["scandir"])?"'".$_GET["scandir"]."'":"null"); + $sql.= ")"; $result2=$db->query($sql); if ($result1 && $result2) { @@ -346,7 +354,7 @@ foreach ($conf->file->dol_document_root as $dirroot) print "<td align=\"center\">\n"; if ($conf->global->COMPANY_ADDON_PDF != "$name") { - print '<a href="'.$_SERVER["PHP_SELF"].'?action=del&value='.$name.'&label='.urlencode($module->name).'">'; + print '<a href="'.$_SERVER["PHP_SELF"].'?action=del&value='.$name.'&scandir='.$module->scandir.'&label='.urlencode($module->name).'">'; print img_picto($langs->trans("Enabled"),'on'); print '</a>'; } @@ -359,7 +367,7 @@ foreach ($conf->file->dol_document_root as $dirroot) else { print "<td align=\"center\">\n"; - print '<a href="'.$_SERVER["PHP_SELF"].'?action=set&value='.$name.'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"),'off').'</a>'; + print '<a href="'.$_SERVER["PHP_SELF"].'?action=set&value='.$name.'&scandir='.$module->scandir.'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"),'off').'</a>'; print "</td>"; } @@ -371,7 +379,7 @@ foreach ($conf->file->dol_document_root as $dirroot) } else { - print '<a href="'.$_SERVER["PHP_SELF"].'?action=setdoc&value='.$name.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"),'off').'</a>'; + 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>'; diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php index 6e3e609dde0..bbb7a164e07 100644 --- a/htdocs/compta/facture.php +++ b/htdocs/compta/facture.php @@ -1425,7 +1425,7 @@ if (($_POST['action'] == 'send' || $_POST['action'] == 'relance') && ! $_POST['a } /* - * Generer ou regenerer le document PDF + * Generate document */ if ($_REQUEST['action'] == 'builddoc') // En get ou en post { diff --git a/htdocs/includes/modules/societe/doc/doc_generic_odt.modules.php b/htdocs/includes/modules/societe/doc/doc_generic_odt.modules.php index e85b8afd135..b98f4cabd97 100644 --- a/htdocs/includes/modules/societe/doc/doc_generic_odt.modules.php +++ b/htdocs/includes/modules/societe/doc/doc_generic_odt.modules.php @@ -53,6 +53,7 @@ class doc_generic_odt extends ModeleThirdPartyDoc $this->db = $db; $this->name = "Generic ODT"; $this->description = $langs->trans("DocumentModelOdt"); + $this->scandir = 'COMPANY_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'; @@ -69,8 +70,8 @@ class doc_generic_odt extends ModeleThirdPartyDoc if (! $this->emetteur->pays_code) $this->emetteur->pays_code=substr($langs->defaultlang,-2); // Par defaut, si n'�tait pas d�fini } - /** \brief Renvoi la description du module - * \return string Texte descripif + /** \brief Return description of a module + * \return string Description */ function info($langs) { @@ -85,13 +86,13 @@ class doc_generic_odt extends ModeleThirdPartyDoc $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="COMPANY_ADDON_PDF_ODTPATH">'; + $texte.= '<input type="hidden" name="param1" value="COMPANY_ADDON_PDF_ODT_PATH">'; $texte.= '<table class="nobordernopadding" width="100%">'; // List of directories area $texte.= '<tr><td>'; $textbis=$langs->trans("ListOfDirectories"); - $listofdir=explode(',',preg_replace('/\r\n/',',',trim($conf->global->COMPANY_ADDON_PDF_ODTPATH))); + $listofdir=explode(',',preg_replace('/[\r\n]+/',',',trim($conf->global->COMPANY_ADDON_PDF_ODT_PATH))); $listoffiles=array(); foreach($listofdir as $key=>$tmpdir) { @@ -109,7 +110,7 @@ class doc_generic_odt extends ModeleThirdPartyDoc //var_dump($listofdir); $texte.= '<textarea class="flat" cols="80" name="value1">'; - $texte.=$conf->global->COMPANY_ADDON_PDF_ODTPATH; + $texte.=$conf->global->COMPANY_ADDON_PDF_ODT_PATH; $texte.= '</textarea>'; // Scan directories @@ -136,12 +137,13 @@ class doc_generic_odt extends ModeleThirdPartyDoc } /** - * \brief Fonction generant le projet sur le disque - * \param delivery Object project a generer - * \param outputlangs Lang output object - * \return int 1 if OK, <=0 if KO + * \brief Function to build a document on disk using the generic odt module. + * \param object Object source to build document + * \param outputlangs Lang output object + * \param $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) + function write_file($object,$outputlangs,$srctemplatepath) { global $user,$langs,$conf; @@ -155,7 +157,7 @@ class doc_generic_odt extends ModeleThirdPartyDoc $outputlangs->load("companies"); $outputlangs->load("projects"); - if ($conf->projet->dir_output) + if ($conf->societe->dir_output) { // If $object is id instead of object if (! is_object($object)) @@ -167,44 +169,67 @@ class doc_generic_odt extends ModeleThirdPartyDoc if ($result < 0) { dol_print_error($db,$object->error); + return -1; } } - $objectref = dol_sanitizeFileName($object->ref); - $dir = $conf->projet->dir_output; + $objectref = dol_sanitizeFileName($object->id); + $dir = $conf->societe->dir_output; if (! preg_match('/specimen/i',$objectref)) $dir.= "/" . $objectref; - $file = $dir . "/" . $objectref . ".pdf"; + $file = $dir . "/" . $objectref . ".odt"; if (! file_exists($dir)) { if (create_exdir($dir) < 0) { $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); - return 0; + return -1; } } if (file_exists($dir)) { - // $file - - + //print "srctemplatepath=".$srctemplatepath; // Src filename + $newfile=basename($srctemplatepath); + $file=$dir.'/'.$newfile; + //print "newdir=".$dir; + //print "newfile=".$newfile; + + create_exdir($conf->societe->dir_temp); + + // Define substitution array + $soc=array('societe'=>'bb','nom'=>'ee','name'=>'tt'); + + // Read template + require_once(DOL_DOCUMENT_ROOT.'/includes/odtphp/odf.php'); + $odfHandler = new odf($srctemplatepath, array( + 'PATH_TO_TMP' => $conf->societe->dir_temp.'/', + 'ZIP_PROXY' => 'PhpZipProxy')); + + // Make substitution + foreach($soc as $socProperty=>$socPropertyValue){ + try { + $odfHandler->setVars($socProperty, $socPropertyValue, true, 'UTF-8'); + } catch(OdfException $e) {} + } + // Write new file + //$result=$odfHandler->exportAsAttachedFile('toto'); + $odfHandler->saveToDisk($file); if (! empty($conf->global->MAIN_UMASK)) @chmod($file, octdec($conf->global->MAIN_UMASK)); - return 1; // Pas d'erreur + return 1; // Success } else { $this->error=$langs->transnoentities("ErrorCanNotCreateDir",$dir); - return 0; + return -1; } } - $this->error=$langs->transnoentities("ErrorConstantNotDefined","LIVRAISON_OUTPUTDIR"); - return 0; + return -1; } } diff --git a/htdocs/includes/modules/societe/modules_societe.class.php b/htdocs/includes/modules/societe/modules_societe.class.php index 9697bfdcd2b..736f08cbe56 100644 --- a/htdocs/includes/modules/societe/modules_societe.class.php +++ b/htdocs/includes/modules/societe/modules_societe.class.php @@ -46,10 +46,9 @@ class ModeleThirdPartyDoc $type='company'; $liste=array(); - $dirtoscan=preg_replace('/\r\n/',',',trim($conf->global->COMPANY_ADDON_PDF_ODTPATH)); include_once(DOL_DOCUMENT_ROOT.'/lib/functions2.lib.php'); - $liste=getListOfModels($db,$type,$dirtoscan); + $liste=getListOfModels($db,$type); return $liste; } @@ -270,4 +269,80 @@ class ModeleAccountancyCode } } + + + +/** + * \brief Create a document for third party + * \param db Database handler + * \param id Id of third party to use + * \param message Message + * \param modele Force model to use ('' to not force). model can be a model name or a template file. + * \param outputlangs Objet lang to use for translation + * \return int <0 if KO, >0 if OK + */ +function thirdparty_doc_create($db, $id, $message, $modele, $outputlangs) +{ + global $conf,$langs; + $langs->load("bills"); + + $dir = DOL_DOCUMENT_ROOT . "/includes/modules/societe/doc"; + $srctemplatepath=''; + + // Positionne modele sur le nom du modele a utiliser + if (! strlen($modele)) + { + if ($conf->global->COMPANY_ADDON_PDF) + { + $modele = $conf->global->COMPANY_ADDON_PDF; + } + else + { + print $langs->trans("Error")." ".$langs->trans("Error_COMPANY_ADDON_PDF_NotDefined"); + return 0; + } + } + + // If selected modele is a filename template (then $modele="modelname:filename") + $tmp=explode(':',$modele,2); + if (! empty($tmp[1])) + { + $modele=$tmp[0]; + $srctemplatepath=$tmp[1]; + } + + // Charge le modele + $file = "doc_".$modele.".modules.php"; + if (file_exists($dir.'/'.$file)) + { + $classname = "doc_".$modele; + require_once($dir.'/'.$file); + + $obj = new $classname($db); + $obj->message = $message; + + // We save charset_output to restore it because write_file can change it if needed for + // output format that does not support UTF8. + $sav_charset_output=$outputlangs->charset_output; + if ($obj->write_file($id, $outputlangs, $srctemplatepath) > 0) + { + $outputlangs->charset_output=$sav_charset_output; + return 1; + } + else + { + $outputlangs->charset_output=$sav_charset_output; + dol_print_error($db,"thirdparty_doc_create Error: ".$obj->error); + return -1; + } + + } + else + { + dol_print_error('',$langs->trans("Error")." ".$langs->trans("ErrorFileDoesNotExists",$dir.'/'.$file)); + return -1; + } +} + + ?> diff --git a/htdocs/includes/odtphp/odf.php b/htdocs/includes/odtphp/odf.php index c611ba6e00f..73fd6c0bcde 100644 --- a/htdocs/includes/odtphp/odf.php +++ b/htdocs/includes/odtphp/odf.php @@ -62,10 +62,10 @@ class Odf } $this->file->close(); - + $tmp = tempnam($this->config['PATH_TO_TMP'], md5(uniqid())); copy($filename, $tmp); - $this->tmpfile = $tmp; + $this->tmpfile = $tmp; $this->_moveRowSegments(); } /** @@ -118,7 +118,7 @@ IMG; * Called automatically within the constructor * * @return void - */ + */ private function _moveRowSegments() { // Search all possible rows in the document @@ -171,7 +171,7 @@ IMG; } /** * Display all the current template variables - * + * * @return string */ public function printVars() @@ -190,7 +190,7 @@ IMG; } /** * Display loop segments declared with setSegment() - * + * * @return string */ public function printDeclaredSegments() @@ -219,7 +219,7 @@ IMG; } /** * Save the odt file on the disk - * + * * @param string $file name of the desired file * @throws OdfException * @return void @@ -231,7 +231,7 @@ IMG; throw new OdfException('Permission denied : can\'t create ' . $file); } $this->_save(); - copy($this->tmpfile, $file); + copy($this->tmpfile, $file); } else { $this->_save(); } @@ -267,19 +267,19 @@ IMG; if (headers_sent($filename, $linenum)) { throw new OdfException("headers already sent ($filename at $linenum)"); } - + if( $name == "" ) { $name = md5(uniqid()) . ".odt"; } - + header('Content-type: application/vnd.oasis.opendocument.text'); header('Content-Disposition: attachment; filename="'.$name.'"'); readfile($this->tmpfile); } /** - * Returns a variable of configuration - * + * Returns a variable of configuration + * * @return string The requested variable of configuration */ public function getConfig($configKey) @@ -291,7 +291,7 @@ IMG; } /** * Returns the temporary working file - * + * * @return string le chemin vers le fichier temporaire de travail */ public function getTmpfile() @@ -300,7 +300,7 @@ IMG; } /** * Delete the temporary file when the object is destroyed - */ + */ public function __destruct() { if (file_exists($this->tmpfile)) { unlink($this->tmpfile); diff --git a/htdocs/langs/fr_FR/admin.lang b/htdocs/langs/fr_FR/admin.lang index e4923913f7b..b8b8a21cce9 100644 --- a/htdocs/langs/fr_FR/admin.lang +++ b/htdocs/langs/fr_FR/admin.lang @@ -267,7 +267,7 @@ MinLength=Longueur minimale LanguageFilesCachedIntoShmopSharedMemory=Fichiers .lang en mémoire partagée ExamplesWithCurrentSetup=Exemples avec le paramétrage actif courant ListOfDirectories=Liste des répertoires de modèles OpenDocument -ListOfDirectoriesForModelGenODT=Liste des répertoires contenant des documents modèles OpenDocument.<br><br>Indiquer le chemin complet du répertoire.<br>Ajouter un retour à la ligne entre chaque répertoire.<br>Pour indiquer un répertoire du module GED, indiquer <b>DOL_DATA_ROOT/ecm/nomdurepertoire</b>.<br><br>Les fichiers modèles dans ces répertoires doivent se terminer par <b>.odt</b>. +ListOfDirectoriesForModelGenODT=Liste des répertoires contenant des documents modèles OpenDocument.<br><br>Indiquer les chemins complets de répertoire.<br>Ajouter un retour à la ligne entre chaque répertoire.<br>Pour indiquer un répertoire du module GED, indiquer<br><b>DOL_DATA_ROOT/ecm/nomdurepertoireged</b><br><br>Les fichiers modèles dans ces répertoires doivent se terminer par <b>.odt</b>. NumberOfModelFilesFound=Nombre de fichiers modèles ODT trouvés dans ce(s) répertoire(s) ExampleOfDirectoriesForModelGen=Exemples de syntaxe:<br>c:\mydir<br>/home/mydir<br>DOL_DATA_ROOT/ecm/ecmdir diff --git a/htdocs/lib/functions2.lib.php b/htdocs/lib/functions2.lib.php index 8d0049ea72c..2bd731fdfb6 100644 --- a/htdocs/lib/functions2.lib.php +++ b/htdocs/lib/functions2.lib.php @@ -1012,18 +1012,19 @@ function picto_from_langcode($codelang) /** - * \brief Return list of activated modules of doc generation + * \brief Return list of activated modules usable for document generation. * \param $db Database handler * \param $type Type of models (company, invoice, ...) - * \param $dirodts List of directories to scan for templates (dir1,dir2,dir3...) - * \return array array(key=>label) + * \return array array(key=>label). For modules that need directory scan, key is completed with ":filename". */ -function getListOfModels($db,$type,$dirtoscan='') +function getListOfModels($db,$type) { global $conf; $liste=array(); - $sql = "SELECT nom as id, nom as lib, libelle as label"; + $dirtoscan=''; + + $sql = "SELECT nom as id, nom as lib, libelle as label, description as description"; $sql.= " FROM ".MAIN_DB_PREFIX."document_model"; $sql.= " WHERE type = '".$type."'"; $sql.= " AND entity = ".$conf->entity; @@ -1037,15 +1038,38 @@ function getListOfModels($db,$type,$dirtoscan='') { $obj = $db->fetch_object($resql); - // We exclude from list generic modules that use directory scans. - // We will add them after. - if (preg_match('/_odt$/',$obj->id)) + // If this generation module needs a directory scan, then description field is filled + // with constant that constains list of directories. + if (! empty($obj->description)) { - $i++; - continue; + $const=$obj->description; + $dirtoscan.=($dirtoscan?',':'').preg_replace('/[\r\n]+/',',',trim($conf->global->$const)); + + $listoffiles=array(); + + // Now we add models found in directories scanned + $listofdir=explode(',',$dirtoscan); + 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)) + { + $tmpfiles=dol_dir_list($tmpdir,'files',0,'\.odt'); + if (sizeof($tmpfiles)) $listoffiles=array_merge($listoffiles,$tmpfiles); + } + } + + foreach($listoffiles as $record) + { + $liste[$obj->id.':'.$record['fullname']]=dol_trunc($record['name'],24,'middle'); + } + } + else + { + $liste[$obj->id]=$obj->label?$obj->label:$obj->lib; } - - $liste[$obj->id]=$obj->label?$obj->label:$obj->lib; $i++; } } @@ -1055,29 +1079,5 @@ function getListOfModels($db,$type,$dirtoscan='') return -1; } - // Now we add models found in directories scanned - if ($dirtoscan) - { - $listofdir=explode(',',$dirtoscan); - $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)) $textbis.=img_warning($langs->trans("ErrorDirNotFound",$tmpdir),0); - else - { - $tmpfiles=dol_dir_list($tmpdir,'files',0,'\.odt'); - if (sizeof($tmpfiles)) $listoffiles=array_merge($listoffiles,$tmpfiles); - } - } - - foreach($listoffiles as $record) - { - $liste[$record['fullname']]=dol_trunc($record['name'],24,'middle'); - } - } - return $liste; } diff --git a/htdocs/soc.php b/htdocs/soc.php index 4fa112f0e7d..c57c27c7f63 100644 --- a/htdocs/soc.php +++ b/htdocs/soc.php @@ -291,6 +291,47 @@ if ($_REQUEST["action"] == 'confirm_delete' && $_REQUEST["confirm"] == 'yes' && } +/* + * Generate document + */ +if ($_REQUEST['action'] == 'builddoc' && ! is_numeric($_REQUEST['model'])) // En get ou en post +{ + require_once(DOL_DOCUMENT_ROOT.'/includes/modules/societe/modules_societe.class.php'); + + $soc = new Societe($db); + $soc->fetch($socid); + $soc->fetch_client(); + + /*if ($_REQUEST['model']) + { + $fac->setDocModel($user, $_REQUEST['model']); + } + */ + + // Define output language + $outputlangs = $langs; + $newlang=''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && ! empty($_REQUEST['lang_id'])) $newlang=$_REQUEST['lang_id']; + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang=$fac->client->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + $result=thirdparty_doc_create($db, $soc->id, '', $_REQUEST['model'], $outputlangs); + if ($result <= 0) + { + dol_print_error($db,$result); + exit; + } + else + { + Header ('Location: '.$_SERVER["PHP_SELF"].'?socid='.$soc->id.(empty($conf->global->MAIN_JUMP_TAG)?'':'#builddoc')); + exit; + } +} + + /* * View */ -- GitLab