Statistiques

Compteur d'affichages des articles
1040160

3 - Méthode Phocca Pdf

Lors de mes recherches, j'ai trouvé comme beaucoup d'entre vous, le composant PhoccaPdf.

Ce composant a l'avantage d'être gratuit mais comme inconvénient, je le vois comme cela, de devoir modifier le coeur de Joomla. Cela ne me convient pas car je n'ai pas envie de tout refaire à chaque mise à jour qui touche le composant com_content.

4 - Méthode Root Progress avec librairie Dompdf

J'ai donc continué à chercher, et je suis tombé sur le plugin de Root Progress. C'est en fait 2 plugins pour le prix d'un.

  • pdfbutton affiche un bouton dans l'article.
  • pdfcontent gère la génération et l'enregistrement du pdf.

4.1 - Téléchargement

Rendez vous sur cette page.

Root Progress Download

Dompdf est déjà installé si vous avez suivi le premier article.

Unzippez le fichier téléchargé et installez les 2 plugins. N'oubliez pas de les activer.

4.2 - Plugin pdfbutton

Plugin pdfbutton

Il suffit de l'activer et de choisir l'emplacement du bouton de génération du PDF.

  • Avant l'article
  • Après l'article
  • Avant et après l'article

Cela donne ceci:

Affichage du bouton d'origine

Cela est très discret. Pour ma part je préfère cela:

Bouton PrestaOpen

Ce bouton a été créé en combinant 2 images trouvées sur le Net avec The Gimp. J'ai renommé le fichier d'origine dans /media/system/images pdf_button.png en pdf_button2.png. Et j'ai enregistré la nouvelle image en pdf_button.png. Pas de modification de code avec cela.

4.3 - Plugin pdfcontent

 Plugin pdfcontent

Vous devez l'activer et définir la taille et l'orientation des pages de votre PDF.

 4.4 - Résultat

Maintenant quand vous cliquez sue le bouton, une fenêtre d'enregistrement apparaît avec le titre de votre article comme nom de fichier.

Voici le fichier:

Fichier PDF

Nous voyons que les images ne sont pas bien gérées. Le problème vient de la réécriture des url des images dans la routine function fullPaths(&$data) dans le fichier plugins/system/pdfcontent/pdfcontent.php.

Les ligne 130 et 131 sont:

				$uri = JUri::getInstance();
				$base = $uri->getScheme() . '://' . $uri->getHost();

				$imgs = $ok->xpath('//img');
				foreach ($imgs as &$img)
				{
					if (!strstr($img['src'], $base))
					{
						$img['src'] = $base . $img['src'];
					}
				}

deviennent:

				$uri = JUri::getInstance();
				$base = $uri->getScheme() . '://' . $uri->getHost();
				$baseimg = JURI::base();

				$imgs = $ok->xpath('//img');
				foreach ($imgs as &$img)
				{
					if (!strstr($img['src'], $baseimg))
					{
						$img['src'] = $baseimg . $img['src'];
					}
				}

Voyons le résultat:

 Nouveau fichier PDF

Les images s'affichent bien, enfin presque , pas toutes les images et la gestion texte/images laisse à désirer. Si dans le fichier plugins/system/pdfcontent/pdfcontent.php nous ajoutons :

				//convert paths in html to full paths
				$this->fullPaths($data);

				//setup dompdf objects
				$pdf = $this->engine;

pour avoir cela

				//convert paths in html to full paths
				$this->fullPaths($data);
echo $data;break;
				//setup dompdf objects
				$pdf = $this->engine;

La fenêtre du navigateur affiche ceci:

 Sortie dans le navigateur

La génération de la variable $data semble correcte, mise à part le centrage des images.

Le problème vient donc de dompdf.

Si l'on regarde sur le site de dompdf, on ne trouve pas beaucoup de documentation. La seule documentation se trouve en étudiant les exemples sur ce lien.

Il est nécessaire d'ajouter des scripts dans le code html contenu dans la variable $data.

Pour réaliser une bonne pagination, il faut ajouter ce code:

<style>
body {
  margin: 18pt 18pt 24pt 18pt;
}

* {
  font-family: helvetica,georgia,serif;
  font-weight: bold;
}

p {
  text-align: justify;
  font-size: 1em;
  margin: 0.5em;
  padding: 10px;
}
</style>
</head>
<body>

<script type="text/php">

if ( isset($pdf) ) {

  $font = Font_Metrics::get_font("verdana");;
  $size = 6;
  $color = array(0,0,0);
  $text_height = Font_Metrics::get_font_height($font, $size);

  $foot = $pdf->open_object();
  
  $w = $pdf->get_width();
  $h = $pdf->get_height();

  // Draw a line along the bottom
  $y = $h - $text_height - 24;
  $pdf->line(16, $y, $w - 16, $y, $color, 0.5);

  $pdf->close_object();
  $pdf->add_object($foot, "all");

  $text = "Page {PAGE_NUM} of {PAGE_COUNT}";  

  // Center the text
  $width = Font_Metrics::get_text_width("Page 1 of 2", $font, $size);
  $pdf->page_text($w / 2 - $width / 2, $y, $text, $font, $size, $color);
  
}
</script>

Voyons si nous pouvons faire cela.

De plus la mise en forme est perturbée par les css du site. Pour empêcher cela nous allons prendre les données dans l'enregistrement de l'article.

Les lignes suivantes :

			$printpdf = JRequest::getInt('pdf');
			if ($printpdf==1) {

				//get document html from joomla cycle
				$data = JResponse::getBody();

				//convert paths in html to full paths
				$this->fullPaths($data);

deviennent :

			$printpdf = JRequest::getInt('pdf');
			if ($printpdf==1) {
				$id = JRequest::getInt('id');
				$db = JFactory::getDBO();
				$query = "SELECT * FROM #__content WHERE id = ".$id." LIMIT 1";
				$db->setQuery($query);
				$result = $db->loadObject();
				//get document html from joomla cycle
				$data = $result->introtext.$result->fulltext;
				$title= $result->title;

				//get document html from joomla cycle
				//$data = JResponse::getBody();

				//convert paths in html to full paths
				//$this->fullPaths($data);

La fonction fullpaths n'est plus nécessaire.

Rajoutons la définition du head et du body dans $data.

Donc après :

				$data = $result->introtext.$result->fulltext;
				$title= $result->title;

Insérons les lignes suivantes :

				// définition des variables
				$a_ajouter_head='<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
				<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr-fr" lang="fr-fr" dir="ltr" >
				<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
				<style type="text/css">
				body { margin: 15 15 15 15;	}
				* { font-family: helvetica,georgia,serif; font-weight: bold;}
				p { text-align: justify; font-size: 1em; margin: 0.5em; padding: 10px; }
				#footer { position: fixed; left: 0; right: 0; color: #aaa; font-size: 0.9em; }
				#all{ margin-top: 150px; }
				#footer { bottom: 0; border-top: 0.1pt solid #aaa; }
				#footer table { width: 100%; border-collapse: collapse; border: none; }
				#footer td { padding: 0; width: 50%; }
				.page-number { text-align: center; }
				.page-number:before { content: "Page " counter(page); }
				</style>
				</head>';
				 $a_ajouter_body='<body>
				<script type="text/php">
				if ( isset($pdf) ) {
				 
				  $font = Font_Metrics::get_font("verdana");;
				  $size = 6;
				  $color = array(0,0,0);
				  $text_height = Font_Metrics::get_font_height($font, $size);
				 
				  $foot = $pdf->open_object();
				   
				  $w = $pdf->get_width();
				  $h = $pdf->get_height();
				 
				  // Draw a line along the bottom
				  $y = $h - $text_height - 24;
				  $pdf->line(16, $y, $w - 16, $y, $color, 0.5);
				 
				  $pdf->close_object();
				  $pdf->add_object($foot, "all");
				  $text = "Page {PAGE_NUM} of {PAGE_COUNT}";  
				 
				  // Center the text
				  $width = Font_Metrics::get_text_width("Page 1 of 2", $font, $size);
				  $pdf->page_text($w / 2 - $width / 2, $y, $text, $font, $size, $color);
				   
				}
				</script>';
				$data=$a_ajouter_head.$a_ajouter_body.$data;

Nous devons aussi modifier une variable dans la configuration de dompdf pour qu'il prenne en compte les définitions float.

Dans librairies/dompdf/dompdf_config.inc.php les lignes :

/**
 * Enable CSS float
 *
 * Allows people to disabled CSS float support
 * @var bool
 */
def("DOMPDF_ENABLE_CSS_FLOAT", false);

deviennent

/**
 * Enable CSS float
 *
 * Allows people to disabled CSS float support
 * @var bool
 */
def("DOMPDF_ENABLE_CSS_FLOAT", true);

Si l'on génère un Pdf:

Float left & right

 

Ici les méthodes float: left & float: right sont bien gérées.

Image centrée

 

Les images centrées ne sont pas bien gérées. Pour améliorer cela il faut remplacer :

<p><img class="caption" src="/images/virtualisation/virtualbox_01.png" border="0" alt="Site Virtualbox" title="Site Virtualbox" style="display: block; margin-left: auto; margin-right: auto;" /></p>

par

<p style="texte-align: center;"><img class="caption" src="/images/virtualisation/virtualbox_01.png" border="0" alt="Site Virtualbox" title="Site Virtualbox" /></p>

Pour pouvoir faire cela, il faut isoler les lignes contenant la balise <img, remplacer <p> par <p style="text-align: center";> et supprimer la définition de style dans la balise <img.

Je décompose la variable $data dans $data_work par un $data_work = explode( "\r\n", $data);

Puis dans chaque ligne de $data_work si je trouve style="display: block; margin-left: auto; margin-right: auto;" je réalise les modifications.

Puis je recompose $data.

Après la ligne :

				$data=$a_ajouter_head.$a_ajouter_body.$data;

On rajoute :

				$data_work = explode( "\r\n", $data);

				for ($j=0, $m=count( $data_work ); $j < $m; $j++) {
						// traitement  style="display: block; margin-left: auto; margin-right: auto;"
						if (stripos($data_work[$j],'style="display: block; margin-left: auto; margin-right: auto;"')!== false) {
							$data_work[$j]=str_replace('style="display: block; margin-left: auto; margin-right: auto;"','',$data_work[$j]);
							$data_work[$j]=str_replace('<p>','<p style="text-align: center;">',$data_work[$j]);
						}
				}
				$data="";
				for ($j=0, $m=count( $data_work ); $j < $m; $j++) {
					$data.=$data_work[$j];
				}

Le Pdf généré ressemble à cela:

Après modifications

Maintenant, les images centrées sont conformes comme les images en float left ou right.

 4.5 - Gestion du header (avec logo et sur la première page seulement)

 Dans la variable $a_ajouter_body après :

				  $pdf->page_text($w / 2 - $width / 2, $y, $text, $font, $size, $color);

rajouter :

				  $image="templates/jp_genesis_j2.5/images/header2.png";
				  $extension= substr($filename, -3, 3);
				  $pdf->image($image,$extension, 0 , 0, getimagesize($image)[1], getimagesize($image)[0]);

Le Pdf généré donne cela :

Header

Le texte du document et le header se chevauchent.

Je n'ai pas trouvé le moyen de définir une marge haute pour la première page différente des autres pages. Je cherche....

En attendant je rajoute des "<br>" en nombre suffisant avant le texte pour qu'il commence après le logo. C'et du bidouillage. Si quelqu'un a la solution, qu'il me le signale par l'intermédiaire des commentaires.

Je modifierais ce document par la suite.

4.6 Footer

Pour ajouter le titre du document dans le footer, il faut modifier:

				  $pdf->page_text($w / 2 - $width / 2, $y, $text, $font, $size, $color);

avec ceci :

				  $pdf->page_text($w / 2 - $width / 2, $y, JFactory::getDocument()->getTitle()." - ".$text, $font, $size, $color);

Voyons voir si l'utilisation de TcPdf nous donne plus de possibilités.