By: Skrol29
Date: 2012-12-21
Time: 00:15
|
Re: Supressing and/or adding slides to a pptx
Here it is, submitted by David L.:
<?php
function cleanPptx($file) {
// Récupère l'archive pptx à nettoyer (suppression des slides superflus).
$zip = $file -> TbsZip;
// Initialise un compteur utile pour connaître le numéro du slide courant dans notre boucle.
$cpt_slide = 1;
// Initialise l'id du slide courant dans notre boucle.
$id_slide = '';
// Initialise l'id de la vue affiliée au slide courant dans notre boucle.
$id_view = '';
// Récupère le fichier récapitulant les différents éléments que contient le document de présentation.
$content = $zip -> FileRead('[Content_Types].xml');
// Récupère le contenu de fichier qui recense les relations entre identifiants et slides.
$presentation_rels = $zip -> FileRead('ppt/_rels/presentation.xml.rels');
// Vérifie si le fichier viewProps.xml est présent dans l'archive.
if ($zip -> FileExists('ppt/_rels/viewProps.xml.rels')) {
$view_rels_exists = true;
// Récupère le contenu du fichier viewProps.xml.rels susceptible de renseigner l'identifiant d'une vue pour un slide.
$view_rels = $zip -> FileRead('ppt/_rels/viewProps.xml.rels');
// Récupère le contenu du fichier viewProps.xml présente les vues.
$view = $zip -> FileRead('ppt/viewProps.xml');
} else {
$view_rels_exists = false;
}
// Récupère le contenu du fichier de presentation.
$presentation = $zip -> FileRead('ppt/presentation.xml');
// Récupère le contenu du fichier qui récapitule les propriétés du document (nombre de slides, titre des slides, etc).
$app = $zip -> FileRead('docProps/app.xml');
// Initialise le tableau comprenant les numéros des slides supprimés.
$slides_supprimes = array();
// Boucle autant de fois qu'il y a de slides (en vérifiant que le fichier xml représentant le slide existe dans l'archive).
while ($zip -> FileExists('ppt/slides/slide' . $cpt_slide . '.xml')) {
// Récupère le contenu du fichier.
$slide = $zip -> FileRead('ppt/slides/slide' . $cpt_slide . '.xml');
// Vérifie si le slide courant contient des balises non remplies.
if (strstr($slide, '%%optional%%')) {
// Supprime le slide courant et le fichier de relation associé.
$zip -> FileReplace('ppt/slides/slide' . $cpt_slide . '.xml', false);
$zip -> FileReplace('ppt/slides/_rels/slide' . $cpt_slide . '.xml.rels', false);
$slides_supprimes[] = $cpt_slide;
//////////////////////////////////////////////////////////
// //
// Début préparation mise à jour [Content_Types].xml //
// //
//////////////////////////////////////////////////////////
$offset = 0;
$fin_boucle = false;
// Boucle sur l'ensemble des éléments que contient le document de présentation jusqu'à ce qu'on trouve celui que l'on souhaite supprimer.
while (! $fin_boucle) {
$debut_chaine = strpos($content, "<Override ", $offset);
$fin_chaine = strpos($content, "/>", $debut_chaine);
// Récupère l'élément courant.
$chaine_temp = substr($content, $debut_chaine, $fin_chaine - $debut_chaine);
// Vérifie si l'élement courant est celui que l'on souhaite supprimer.
if (strstr($chaine_temp, 'slide' . $cpt_slide . '.xml') != false) {
// Définit le contenu à jour du fichier .
$content = substr($content, 0, $debut_chaine) . substr($content, $fin_chaine + 2, strlen($content) - $fin_chaine + 1);
$fin_boucle = true;
}
$offset = $fin_chaine + 2;
}
//////////////////////////////////////////////////////////
// //
// Fin préparation mise à jour [Content_Types].xml //
// //
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
// //
// Début préparation mise à jour presentation.xml.rels //
// //
//////////////////////////////////////////////////////////
$offset = 0;
$fin_boucle = false;
// Boucle sur l'ensemble des relations entre identifiants et slides définies dans le fichier jusqu'à ce qu'on trouve celle que l'on souhaite supprimer.
while (! $fin_boucle) {
$debut_chaine = strpos($presentation_rels, "<Relationship ", $offset);
$fin_chaine = strpos($presentation_rels, "/>", $debut_chaine);
// Récupère la relation courante.
$chaine_temp = substr($presentation_rels, $debut_chaine, $fin_chaine - $debut_chaine);
// Vérifie si la relation courante est celle que l'on souhaite supprimer.
if (strstr($chaine_temp, 'slide' . $cpt_slide . '.xml') != false) {
// Définit le contenu à jour du fichier qui recense les relations entre identifiants et slides (suppression de la relation courante).
$presentation_rels = substr($presentation_rels, 0, $debut_chaine) . substr($presentation_rels, $fin_chaine + 2, strlen($presentation_rels) - $fin_chaine + 1);
$debut_chaine = strpos($chaine_temp, "Id=\"");
$fin_chaine = strpos($chaine_temp, "\" Type");
// Récupère de l'id de la relation courante. Utile pour supprimer par la suite une ligne dans la fichier de presentation.
$id_slide = substr($chaine_temp, $debut_chaine + 4, $fin_chaine - $debut_chaine - 4);
$fin_boucle = true;
}
$offset = $fin_chaine + 2;
}
//////////////////////////////////////////////////////////
// //
// Fin préparation mise à jour presentation.xml.rels //
// //
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
// //
// Début préparation mise à jour viewProps.xml.rels //
// & viewProps.xml //
// //
//////////////////////////////////////////////////////////
if ($view_rels_exists) {
// Vérifie si viewProps.xml.rels contient des vues relatives au slide courant à supprimer.
if (strstr($view_rels, 'slide' . $cpt_slide . '.xml') != false) {
$offset = 0;
$fin_boucle = false;
// Boucle sur l'ensemble des relations entre vues et slides définies dans le fichier jusqu'à ce qu'on trouve celle que l'on souhaite supprimer.
while (! $fin_boucle) {
$debut_chaine = strpos($view_rels, "<Relationship ", $offset);
$fin_chaine = strpos($view_rels, "/>", $debut_chaine);
// Récupère la relation courante.
$chaine_temp = substr($view_rels, $debut_chaine, $fin_chaine - $debut_chaine);
// Vérifie si la relation courante est celle que l'on souhaite supprimer.
if (strstr($chaine_temp, 'slide' . $cpt_slide . '.xml') != false) {
// Définit le contenu à jour du fichier viewProps.xml.rels en supprimant la relation obsolète.
$view_rels = substr($view_rels, 0, $debut_chaine) . substr($view_rels, $fin_chaine + 2, strlen($view_rels) - $fin_chaine - 2);
$debut_chaine = strpos($chaine_temp, "Id=\"");
$fin_chaine = strpos($chaine_temp, "\" Type");
// Récupère de l'id de la relation courante. Utile pour supprimer par la suite une ligne dans la fichier de présentation des vues.
$id_view = substr($chaine_temp, $debut_chaine + 4, $fin_chaine - $debut_chaine - 4);
$fin_boucle = true;
}
$offset = $fin_chaine + 2;
}
$offset = 0;
$fin_boucle = false;
// Boucle sur l'ensemble des identifiants listés dans le fichier viewProps.xml présentant les vues.
while (! $fin_boucle) {
$debut_chaine = strpos($view, "<p:sld r:id", $offset);
$fin_chaine = strpos($view, "/>", $debut_chaine);
// Récupère l'id courant.
$chaine_temp = substr($view, $debut_chaine, $fin_chaine - $debut_chaine);
// Vérifie si l'id courant est celui que l'on souhaite supprimer.
if (strstr($chaine_temp, $id_view) != false) {
// Définit le contenu à jour du fichier de présentation des vues (suppression de l'id courant).
$view = substr($view, 0, $debut_chaine) . substr($view, $fin_chaine + 2, strlen($view) - $fin_chaine - 2);
$fin_boucle = true;
}
$offset = $fin_chaine + 2;
}
}
}
//////////////////////////////////////////////////////////
// //
// Fin préparation mise à jour viewProps.xml.rels //
// & viewProps.xml //
// //
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
// //
// Début préparation mise à jour presentation.xml //
// //
//////////////////////////////////////////////////////////
$offset = 0;
$fin_boucle = false;
// Boucle sur l'ensemble des définitions d'identifiant dans le fichier de présentation jusqu'à ce qu'on trouve celle que l'on souhaite supprimer.
while (! $fin_boucle) {
$debut_chaine = strpos($presentation, "<p:sldId ", $offset);
$fin_chaine = strpos($presentation, "/>", $debut_chaine);
// Récupère l'id courant.
$chaine_temp = substr($presentation, $debut_chaine, $fin_chaine - $debut_chaine);
// Vérifie si l'id courant est celui que l'on souhaite supprimer.
if (strstr($chaine_temp, $id_slide) != false) {
// Définit le contenu à jour du fichier de présentation (suppression de l'id courant).
$presentation = substr($presentation, 0, $debut_chaine) . substr($presentation, $fin_chaine + 2, strlen($presentation) - $fin_chaine + 1);
$fin_boucle = true;
}
$offset = $fin_chaine + 2;
}
//////////////////////////////////////////////////////////
// //
// Fin préparation mise à jour presentation.xml //
// //
//////////////////////////////////////////////////////////
}
// Remplace les différents fichiers xml utiles du document de présentation par les mises à jour construites dans le tratitement ci-dessus.
$zip -> FileReplace('[Content_Types].xml', $content, TBSZIP_STRING);
$zip -> FileReplace('ppt/_rels/presentation.xml.rels', $presentation_rels, TBSZIP_STRING);
if ($view_rels_exists) {
$zip -> FileReplace('ppt/_rels/viewProps.xml.rels', $view_rels, TBSZIP_STRING);
$zip -> FileReplace('ppt/viewProps.xml', $view, TBSZIP_STRING);
}
$zip -> FileReplace('ppt/presentation.xml', $presentation, TBSZIP_STRING);
++ $cpt_slide;
}
//////////////////////////////////////////////////////////
// //
// Début préparation mise à jour app.xml //
// //
//////////////////////////////////////////////////////////
if (count($slides_supprimes) > 0) {
$debut_chaine = strpos($app, "<Slides>");
$fin_chaine = strpos($app, "</Slides>");
// Récupère le nombre de slides total du document de présentation mis à jour.
$nb_slides = substr($app, $debut_chaine + 8, $fin_chaine - $debut_chaine - 8) - count($slides_supprimes);;
// Définit le contenu à jour du fichier app.xml qui récapitule les propriétés du document.
$app = substr($app, 0, $debut_chaine + 8) . $nb_slides . substr($app, $fin_chaine, strlen($app) - $fin_chaine);
$fin_boucle = false;
$offset = 0;
$nb_polices = 0;
$nb_themes = 0;
// Boucle sur les balises i4 afin de déterminer le nom de polices et thèmes (utile pour la suite) et mettre à jour le nombre de slides.
while (! $fin_boucle) {
$debut_chaine = strpos($app, "<vt:i4>", $offset);
$fin_chaine = strpos($app, "</vt:i4>", $debut_chaine);
$debut_chaine_bis = strpos($app, "<vt:lpstr>", $offset);
$fin_chaine_bis = strpos($app, "</vt:lpstr>", $debut_chaine_bis);
$propriete = substr($app, $debut_chaine_bis + 10, $fin_chaine_bis - $debut_chaine_bis - 10);
if ($propriete == "Polices utilisées") {
// Récupère le nombre de polices utilisées au sein du document de présentation.
$nb_polices = substr($app, $debut_chaine + 7, $fin_chaine - $debut_chaine - 7);
} else if ($propriete == "Thème") {
// Récupère le nombre de thèmes utilisés au sein du document de présentation.
$nb_themes = substr($app, $debut_chaine + 7, $fin_chaine - $debut_chaine - 7);
} else if ($propriete == "Titres des diapositives") {
// Définit le contenu à jour du fichier app.xml qui récapitule les propriétés du document.
$app = substr($app, 0, $debut_chaine + 7) . $nb_slides . substr($app, $fin_chaine, strlen($app) - $fin_chaine);
$fin_boucle = true;
}
$offset = $fin_chaine;
}
$debut_chaine = strrpos($app, "<vt:vector size=\"");
$fin_chaine = strpos($app, "\" baseType=\"lpstr\">", $debut_chaine);
// Récupère le nombre de balises lpstr mis à jour.
$lpstr = substr($app, $debut_chaine + 17, $fin_chaine - $debut_chaine - 17) - count($slides_supprimes);
// Définit le contenu à jour du fichier app.xml qui récapitule les propriétés du document.
$app = substr($app, 0, $debut_chaine + 17) . $lpstr . substr($app, $fin_chaine, strlen($app) - $fin_chaine);
// Définit la balise lpstr à supprimer (balise contenant le titre du slide courant à supprimer).
$lpstr_delete = $nb_polices + $nb_themes + $cpt_slide;
$offset = $fin_chaine;
// Boucle sur les balises lpstr jusqu'à celle à supprimer puis on met à jour le fichier app.xml qui récapitule les propriétés du document.
for ($i = 1 - $nb_polices - $nb_themes ; $i <= $lpstr_delete ; ++ $i) {
$debut_chaine = strpos($app, "<vt:lpstr>", $offset);
$fin_chaine = strpos($app, "</vt:lpstr>", $debut_chaine);
if (in_array($i, $slides_supprimes)) {
// Définit le contenu à jour du fichier app.xml qui récapitule les propriétés du document.
$app = substr($app, 0, $debut_chaine) . substr($app, $fin_chaine + 11, strlen($app) - $fin_chaine - 11);
} else {
$offset = $fin_chaine;
}
}
// Met à jour le fichier app.xml qui récapitule les propriétés du document.
$zip -> FileReplace('docProps/app.xml', $app, TBSZIP_STRING);
}
//////////////////////////////////////////////////////////
// //
// Fin préparation mise à jour app.xml //
// //
//////////////////////////////////////////////////////////
}
?> |
|