Gestionar comentarios de presentaciones en PHP
Visión general
Este artículo explica cómo gestionar los comentarios de presentaciones con Aspose.Slides para PHP mediante Java. Presenta los tipos principales relacionados con los comentarios y muestra cómo añadir comentarios a las diapositivas, acceder a los comentarios existentes, trabajar con respuestas y comentarios modernos, y eliminar comentarios de una presentación.
Los ejemplos abarcan escenarios comunes de revisión y colaboración en PowerPoint, como asignar comentarios a autores, leer el texto y los metadatos de los comentarios, crear cadenas de respuestas y eliminar comentarios seleccionados o todos los comentarios.
En PowerPoint, los comentarios aparecen como anotaciones en las diapositivas. Seleccionar un comentario muestra su texto y la discusión relacionada.
¿Por qué añadir comentarios a las presentaciones?
Puede usar los comentarios para proporcionar retroalimentación y colaborar con colegas al revisar presentaciones.
Aspose.Slides para PHP mediante Java ofrece las siguientes API para trabajar con comentarios:
- La clase Presentation que proporciona acceso a los autores de comentarios de la presentación.
- La clase CommentCollection que representa los comentarios asociados a un autor individual.
- La clase Comment que proporciona información sobre un comentario, incluido su autor, tiempo de creación, posición y texto.
- La clase CommentAuthor que proporciona información sobre un autor, incluido su nombre, iniciales y los comentarios asociados.
Añadir comentarios a diapositivas
El siguiente ejemplo muestra cómo añadir comentarios a diapositivas en una presentación de PowerPoint:
use aspose\slides\Point2DFloat;
use aspose\slides\Presentation;
use aspose\slides\SaveFormat;
$presentation = new Presentation();
try {
$firstSlide = $presentation->getSlides()->get_Item(0);
$secondSlide = $presentation->getSlides()->addEmptySlide($presentation->getLayoutSlides()->get_Item(0));
$author = $presentation->getCommentAuthors()->addAuthor("Jawad", "MF");
$position = new Point2DFloat(0.2, 0.2);
$createdTime = new Java("java.util.Date");
$author->getComments()->addComment("Hello Jawad, this is a slide comment", $firstSlide, $position, $createdTime);
$author->getComments()->addComment("Hello Jawad, this is the second slide comment", $secondSlide, $position, $createdTime);
$comments = $firstSlide->getSlideComments($author);
$arrayClass = new JavaClass("java.lang.reflect.Array");
$commentCount = java_values($arrayClass->getLength($comments));
if ($commentCount > 0) {
$firstComment = $comments[0];
echo java_values($firstComment->getText()) . PHP_EOL;
$authorComments = $firstComment->getAuthor()->getComments();
$commentText = $authorComments->get_Item(0)->getText();
echo java_values($commentText) . PHP_EOL;
}
$presentation->save("Comments_out.pptx", SaveFormat::Pptx);
} finally {
$presentation->dispose();
}
Acceder a comentarios de diapositivas
El siguiente ejemplo muestra cómo acceder a los comentarios existentes en una presentación de PowerPoint:
use aspose\slides\Presentation;
$presentation = new Presentation("Comments1.pptx");
try {
foreach ($presentation->getCommentAuthors() as $author) {
foreach ($author->getComments() as $comment) {
echo "Slide: " . java_values($comment->getSlide()->getSlideNumber()) . PHP_EOL;
echo "Comment: " . java_values($comment->getText()) . PHP_EOL;
echo "Author: " . java_values($comment->getAuthor()->getName()) . PHP_EOL;
echo "Posted at: " . java_values($comment->getCreatedTime()->toString()) . PHP_EOL;
echo PHP_EOL;
}
}
} finally {
$presentation->dispose();
}
Responder a comentarios
Un comentario padre es el comentario original en la parte superior de una jerarquía de respuestas. Los métodos Comment::getParentComment y Comment::setParentComment le permiten obtener o establecer el padre de un comentario.
El siguiente ejemplo muestra cómo añadir respuestas e inspeccionar la jerarquía de comentarios resultante:
use aspose\slides\Point2DFloat;
use aspose\slides\Presentation;
use aspose\slides\SaveFormat;
$presentation = new Presentation();
try {
$slide = $presentation->getSlides()->get_Item(0);
$position = new Point2DFloat(10, 10);
$createdTime = new Java("java.util.Date");
$author1 = $presentation->getCommentAuthors()->addAuthor("Author_1", "A.A.");
$comment1 = $author1->getComments()->addComment("comment 1", $slide, $position, $createdTime);
$author2 = $presentation->getCommentAuthors()->addAuthor("Author_2", "B.B.");
$reply1 = $author2->getComments()->addComment("reply 1 for comment 1", $slide, $position, $createdTime);
$reply1->setParentComment($comment1);
$reply2 = $author2->getComments()->addComment("reply 2 for comment 1", $slide, $position, $createdTime);
$reply2->setParentComment($comment1);
$subReply = $author1->getComments()->addComment("subreply 3 for reply 2", $slide, $position, $createdTime);
$subReply->setParentComment($reply2);
$author2->getComments()->addComment("comment 2", $slide, $position, $createdTime);
$comment3 = $author2->getComments()->addComment("comment 3", $slide, $position, $createdTime);
$reply3 = $author1->getComments()->addComment("reply 4 for comment 3", $slide, $position, $createdTime);
$reply3->setParentComment($comment3);
$comments = $slide->getSlideComments(null);
$arrayClass = new JavaClass("java.lang.reflect.Array");
$commentCount = java_values($arrayClass->getLength($comments));
for ($i = 0; $i < $commentCount; $i++) {
$comment = $comments[$i];
while (!java_is_null($comment->getParentComment())) {
echo "\t";
$comment = $comment->getParentComment();
}
echo java_values($comments[$i]->getAuthor()->getName()) . ": " . java_values($comments[$i]->getText()) . PHP_EOL;
}
$presentation->save("parent_comment.pptx", SaveFormat::Pptx);
$comment1->remove();
$presentation->save("remove_comment.pptx", SaveFormat::Pptx);
} finally {
$presentation->dispose();
}
Warning
- Cuando se utiliza el método Comment::remove para eliminar un comentario, también se eliminan todas las respuestas a ese comentario.
- Si Comment::setParentComment crea una referencia circular, se lanza una PptxEditException.
Añadir comentarios modernos
Los comentarios modernos pueden asociarse a la propia diapositiva, a una forma específica o a un rango de texto dentro de una AutoShape. El método CommentCollection::addModernComment acepta un argumento Shape además de la diapositiva y las coordenadas del marcador del comentario.
Cuando se pasa null para el argumento de forma, el comentario es un comentario a nivel de diapositiva. Su marcador se posiciona mediante las coordenadas proporcionadas, pero no está asociado a una forma concreta, por lo que ModernComment::getShape devuelve null. Cuando se suministra una Shape, el comentario se ancla a esa forma. Las coordenadas siguen definiendo la posición del marcador del comentario en la diapositiva, mientras que la asociación con la forma puede obtenerse a través de ModernComment::getShape.
Anclar un comentario moderno a una forma
El siguiente ejemplo crea tanto un comentario moderno a nivel de diapositiva como un comentario moderno anclado a una AutoShape específica. Luego lee la forma asociada de cada comentario.
use aspose\slides\Point2DFloat;
use aspose\slides\Presentation;
use aspose\slides\SaveFormat;
use aspose\slides\ShapeType;
$presentation = new Presentation();
try {
$slide = $presentation->getSlides()->get_Item(0);
$author = $presentation->getCommentAuthors()->addAuthor("Reviewer", "RV");
$shape = $slide->getShapes()->addAutoShape(ShapeType::Rectangle, 50, 50, 300, 80);
$shape->setName("Revenue title");
$shape->getTextFrame()->setText("Quarterly revenue");
$createdTime = new Java("java.util.Date");
$slideCommentPosition = new Point2DFloat(20, 20);
$shapeCommentPosition = new Point2DFloat(60, 60);
$slideComment = $author->getComments()->addModernComment("Review the overall slide layout.", $slide, null, $slideCommentPosition, $createdTime);
$shapeComment = $author->getComments()->addModernComment("Check this title.", $slide, $shape, $shapeCommentPosition, $createdTime);
echo (java_is_null($slideComment->getShape()) ? "true" : "false") . PHP_EOL;
echo java_values($shapeComment->getShape()->getName()) . PHP_EOL;
$presentation->save("modern_comments.pptx", SaveFormat::Pptx);
} finally {
$presentation->dispose();
}
Anclar comentarios a diferentes tipos de forma
Cualquier objeto de diapositiva representado por la clase Shape puede usarse como ancla de forma. Los ejemplos más habituales incluyen AutoShape, PictureFrame, GroupShape, Connector y GraphicalObject como gráficos.
El siguiente ejemplo crea varios tipos de forma comunes y asocia un comentario moderno con cada una de ellas.
use aspose\slides\ChartType;
use aspose\slides\Point2DFloat;
use aspose\slides\Presentation;
use aspose\slides\SaveFormat;
use aspose\slides\ShapeType;
$presentation = new Presentation();
try {
$slide = $presentation->getSlides()->get_Item(0);
$author = $presentation->getCommentAuthors()->addAuthor("Reviewer", "RV");
$createdTime = new Java("java.util.Date");
$autoShape = $slide->getShapes()->addAutoShape(ShapeType::Rectangle, 20, 20, 180, 60);
$autoShape->getTextFrame()->setText("AutoShape");
$autoShapeCommentPosition = new Point2DFloat(30, 30);
$author->getComments()->addModernComment("Comment on an AutoShape.", $slide, $autoShape, $autoShapeCommentPosition, $createdTime);
$imageBase64 = "iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAAFklEQVR4nGP8//8/AwMDEwMDAwMDAwAkBgMB/DXemwAAAABJRU5ErkJggg==";
$base64Class = new JavaClass("java.util.Base64");
$imageData = $base64Class->getDecoder()->decode($imageBase64);
$image = $presentation->getImages()->addImage($imageData);
$pictureFrame = $slide->getShapes()->addPictureFrame(ShapeType::Rectangle, 220, 20, 120, 80, $image);
$pictureCommentPosition = new Point2DFloat(230, 30);
$author->getComments()->addModernComment("Comment on a picture.", $slide, $pictureFrame, $pictureCommentPosition, $createdTime);
$groupShape = $slide->getShapes()->addGroupShape();
$groupShape->getShapes()->addAutoShape(ShapeType::Rectangle, 0, 0, 80, 40);
$groupShape->getShapes()->addAutoShape(ShapeType::Ellipse, 100, 0, 80, 40);
$groupCommentPosition = new Point2DFloat(40, 150);
$author->getComments()->addModernComment("Comment on a group.", $slide, $groupShape, $groupCommentPosition, $createdTime);
$connector = $slide->getShapes()->addConnector(ShapeType::StraightConnector1, 220, 150, 140, 40);
$connectorCommentPosition = new Point2DFloat(240, 150);
$author->getComments()->addModernComment("Comment on a connector.", $slide, $connector, $connectorCommentPosition, $createdTime);
$chart = $slide->getShapes()->addChart(ChartType::ClusteredColumn, 400, 20, 250, 180);
$chartCommentPosition = new Point2DFloat(420, 40);
$author->getComments()->addModernComment("Comment on a graphical object.", $slide, $chart, $chartCommentPosition, $createdTime);
$presentation->save("modern_comment_shape_types.pptx", SaveFormat::Pptx);
} finally {
$presentation->dispose();
}
Anclar un comentario a texto y establecer su estado
Para un comentario moderno asociado a una AutoShape, los métodos ModernComment::getTextSelectionStart y ModernComment::setTextSelectionStart acceden a la posición inicial del texto seleccionado en el marco de texto de la forma. Los métodos ModernComment::getTextSelectionLength y ModernComment::setTextSelectionLength acceden a la longitud de la selección. Juntos, estos valores asocian el comentario a un rango de texto específico dentro de la AutoShape.
Los métodos ModernComment::getStatus y ModernComment::setStatus acceden a un valor de las constantes ModernCommentStatus:
NotDefined— no se ha definido un estado específico para el comentario moderno.Active— el comentario está activo.Resolved— el comentario se ha resuelto.Closed— el comentario está cerrado.
El siguiente ejemplo crea un comentario moderno anclado a una forma, lo asocia a una selección de texto, lo marca como resuelto, guarda la presentación y verifica los valores después de volver a abrir el archivo.
use aspose\slides\ModernCommentStatus;
use aspose\slides\Point2DFloat;
use aspose\slides\Presentation;
use aspose\slides\SaveFormat;
use aspose\slides\ShapeType;
$outputFile = "modern_comment_text_anchor.pptx";
$shapeText = "Review the quarterly revenue forecast.";
$selectedText = "quarterly revenue";
$expectedSelectionStart = strpos($shapeText, $selectedText);
$presentation = new Presentation();
try {
$slide = $presentation->getSlides()->get_Item(0);
$shape = $slide->getShapes()->addAutoShape(ShapeType::Rectangle, 50, 50, 400, 100);
$shape->setName("Forecast text");
$shape->getTextFrame()->setText($shapeText);
$author = $presentation->getCommentAuthors()->addAuthor("Reviewer", "RV");
$commentPosition = new Point2DFloat(60, 60);
$comment = $author->getComments()->addModernComment("Verify this forecast wording.", $slide, $shape, $commentPosition, new Java("java.util.Date"));
$comment->setTextSelectionStart($expectedSelectionStart);
$comment->setTextSelectionLength(strlen($selectedText));
$comment->setStatus(ModernCommentStatus::Resolved);
$presentation->save($outputFile, SaveFormat::Pptx);
} finally {
$presentation->dispose();
}
$reopenedPresentation = new Presentation($outputFile);
try {
$reopenedSlide = $reopenedPresentation->getSlides()->get_Item(0);
$reopenedComments = $reopenedSlide->getSlideComments(null);
$modernCommentClass = new JavaClass("com.aspose.slides.ModernComment");
foreach ($reopenedComments as $reopenedComment) {
if (!java_instanceof($reopenedComment, $modernCommentClass)) {
continue;
}
$shape = $reopenedComment->getShape();
$shapeMatches = !java_is_null($shape) && java_values($shape->getName()) === "Forecast text";
$selectionStartMatches = java_values($reopenedComment->getTextSelectionStart()) === $expectedSelectionStart;
$selectionLengthMatches = java_values($reopenedComment->getTextSelectionLength()) === strlen($selectedText);
$statusMatches = java_values($reopenedComment->getStatus()) === ModernCommentStatus::Resolved;
echo "Shape anchor preserved: " . ($shapeMatches ? "true" : "false") . PHP_EOL;
echo "Text selection start preserved: " . ($selectionStartMatches ? "true" : "false") . PHP_EOL;
echo "Text selection length preserved: " . ($selectionLengthMatches ? "true" : "false") . PHP_EOL;
echo "Resolved status preserved: " . ($statusMatches ? "true" : "false") . PHP_EOL;
}
} finally {
$reopenedPresentation->dispose();
}
Inspeccionar comentarios modernos existentes
Para inspeccionar una presentación existente, compruebe si cada comentario es un ModernComment, luego examine ModernComment::getShape, ModernComment::getTextSelectionStart, ModernComment::getTextSelectionLength y ModernComment::getStatus. Una forma null indica un comentario a nivel de diapositiva. Para un ancla de AutoShape, los métodos de selección de texto identifican el rango asociado en el marco de texto de la forma.
use aspose\slides\Presentation;
$presentation = new Presentation("comments.pptx");
try {
$modernCommentClass = new JavaClass("com.aspose.slides.ModernComment");
$autoShapeClass = new JavaClass("com.aspose.slides.AutoShape");
foreach ($presentation->getSlides() as $slide) {
$comments = $slide->getSlideComments(null);
foreach ($comments as $comment) {
if (!java_instanceof($comment, $modernCommentClass)) {
continue;
}
echo "Slide: " . java_values($slide->getSlideNumber()) . PHP_EOL;
echo "Text: " . java_values($comment->getText()) . PHP_EOL;
echo "Status: " . java_values($comment->getStatus()) . PHP_EOL;
$shape = $comment->getShape();
if (java_is_null($shape)) {
echo "Anchor: slide level" . PHP_EOL;
} else {
echo "Anchor shape: " . java_values($shape->getName()) . PHP_EOL;
echo "Anchor type: " . java_values($shape->getClass()->getSimpleName()) . PHP_EOL;
if (java_instanceof($shape, $autoShapeClass)) {
echo "Text selection start: " . java_values($comment->getTextSelectionStart()) . PHP_EOL;
echo "Text selection length: " . java_values($comment->getTextSelectionLength()) . PHP_EOL;
}
}
echo PHP_EOL;
}
}
} finally {
$presentation->dispose();
}
Eliminar comentarios
Eliminar todos los comentarios y autores de comentarios
El siguiente ejemplo muestra cómo eliminar todos los comentarios y autores de comentarios de una presentación:
use aspose\slides\Presentation;
use aspose\slides\SaveFormat;
$presentation = new Presentation("example.pptx");
try {
foreach ($presentation->getCommentAuthors() as $author) {
$author->getComments()->clear();
}
$presentation->getCommentAuthors()->clear();
$presentation->save("example_out.pptx", SaveFormat::Pptx);
} finally {
$presentation->dispose();
}
Eliminar comentarios específicos
El siguiente ejemplo muestra cómo eliminar comentarios específicos de una diapositiva:
use aspose\slides\Point2DFloat;
use aspose\slides\Presentation;
use aspose\slides\SaveFormat;
$presentation = new Presentation();
try {
$slide = $presentation->getSlides()->get_Item(0);
$author = $presentation->getCommentAuthors()->addAuthor("Author", "A");
$createdTime = new Java("java.util.Date");
$firstCommentPosition = new Point2DFloat(0.2, 0.2);
$secondCommentPosition = new Point2DFloat(0.3, 0.2);
$author->getComments()->addComment("comment 1", $slide, $firstCommentPosition, $createdTime);
$author->getComments()->addComment("comment 2", $slide, $secondCommentPosition, $createdTime);
foreach ($presentation->getCommentAuthors() as $commentAuthor) {
$commentsToRemove = new Java("java.util.ArrayList");
$comments = $slide->getSlideComments($commentAuthor);
foreach ($comments as $comment) {
if ($comment->getText()->equals("comment 1")) {
$commentsToRemove->add($comment);
}
}
foreach ($commentsToRemove as $comment) {
$commentAuthor->getComments()->remove($comment);
}
}
$presentation->save("pres.pptx", SaveFormat::Pptx);
} finally {
$presentation->dispose();
}
Preguntas frecuentes
¿Aspose.Slides admite un estado resuelto para los comentarios modernos?
Sí. Los métodos ModernComment::getStatus y ModernComment::setStatus acceden a un valor de ModernCommentStatus, incluido Resolved. El estado se almacena en la presentación y puede leerse nuevamente después de volver a abrir el archivo.
¿Se admiten discusiones en hilos (cadenas de respuestas) y hay un límite de anidación?
Sí. Cada comentario puede referenciar su parent comment, lo que permite crear cadenas de respuestas. La API no define un límite específico de profundidad de anidación.
¿En qué sistema de coordenadas se define la posición del marcador de comentario en una diapositiva?
La posición del marcador se define mediante coordenadas de punto flotante en el sistema de coordenadas de la diapositiva, lo que permite colocarlo con precisión en la diapositiva.