Hyperlink Support for Ods (#3669)

Fix #3660. Code existed to read a hyperlink in a cell for Ods, but did not exist for writing. Hyperlinks pointing within a document use a different representation than for Excel (and therefore for PhpSpreadsheet); read and write will both handle the mapping from one to the other.

While researching how to write the text part of a started Xml element, it transpired that writing 2 Ods properties (Company and Category) did not escape their values properly. Confirmed and fixed problem. I do not believe that there is such an exposure for any other writer. As it turns out, Ods Reader was not processing Company or Category properly; that is fixed.
This commit is contained in:
oleibman
2023-08-12 07:29:20 -07:00
committed by GitHub
parent efd04e6b81
commit 6f5ef037be
5 changed files with 82 additions and 4 deletions
@@ -0,0 +1,52 @@
<?php
namespace PhpOffice\PhpSpreadsheetTests\Reader\Ods;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Ods;
use PhpOffice\PhpSpreadsheetTests\Functional\AbstractFunctional;
class HyperlinkTest extends AbstractFunctional
{
public function testSaveAndLoadHyperlinks(): void
{
$spreadsheetOld = new Spreadsheet();
$spreadsheetOld->getProperties()->setCompany('g</meta:user-defined>zorg');
$spreadsheetOld->getProperties()->setCategory('h</meta:user-defined>zorg');
$sheet = $spreadsheetOld->getActiveSheet();
$sheet->getCell('A1')->setValue('Hello World');
$sheet->getCell('A2')->setValue('http://example.org');
$sheet->getCell('A2')->getHyperlink()->setUrl('http://example.org/');
$sheet->getCell('A3')->setValue('pa<ge1');
$sheet->getCell('A3')->getHyperlink()->setUrl('http://example.org/page1.html');
$sheet2 = $spreadsheetOld->createSheet();
$sheet2->setTitle('TargetSheet');
$sheet2->setCellValue('B4', 'TargetCell');
$sheet2->setCellValue('B3', 'not target');
$sheet->getCell('A4')->setValue('go to Target');
$sheet->getCell('A4')->getHyperlink()->setUrl('sheet://TargetSheet!B4');
$spreadsheet = $this->writeAndReload($spreadsheetOld, 'Ods');
$spreadsheetOld->disconnectWorksheets();
$newSheet = $spreadsheet->getActiveSheet();
self::assertSame('g</meta:user-defined>zorg', $spreadsheet->getProperties()->getCompany());
self::assertSame('h</meta:user-defined>zorg', $spreadsheet->getProperties()->getCategory());
self::assertSame('http://example.org', $newSheet->getCell('A2')->getValue());
self::assertSame('http://example.org/', $newSheet->getCell('A2')->getHyperlink()->getUrl());
self::assertSame('pa<ge1', $newSheet->getCell('A3')->getValue());
self::assertSame('http://example.org/page1.html', $newSheet->getCell('A3')->getHyperlink()->getUrl());
self::assertSame('go to Target', $newSheet->getCell('A4')->getValue());
self::assertSame('sheet://TargetSheet!B4', $newSheet->getCell('A4')->getHyperlink()->getUrl());
// Verify that http links are unchanged,
// but internal sheet link has changed.
$writer = new Ods($spreadsheet);
$content = $writer->getWriterPartContent()->write();
self::assertStringContainsString('xlink:href="http://example.org/"', $content);
self::assertStringContainsString('xlink:href="http://example.org/page1.html"', $content);
self::assertStringContainsString('xlink:href="#TargetSheet!B4"', $content);
self::assertStringNotContainsString('sheet:', $content);
$spreadsheet->disconnectWorksheets();
}
}