Repository navigation
RIGHT: return all of the text when num_chars exceeds its length - #5044
Merged
Merged
Conversation
RIGHT("abc",5) returned "bc" because the start offset went negative and
mb_substr then counted it from the end of the string. Excel returns the
whole text when num_chars is greater than its length, so clamp the offset
at 0.
Collaborator
|
Thank you for your contribution. |
Vitexus
added a commit
to Spoje-NET/php-phpoffice-phpspreadsheet
that referenced
this pull request
Nov 12, 2026
## 2026-11-07 - 5.11.0 ### Added - Ods Writer writes each table as a named database range, with its header row, so that LibreOffice tags the header cells of an exported PDF as `/TH`; Ods Reader reads a named database range back as a table (the anonymous range LibreOffice keeps for the filter of a sheet stays that sheet's autofilter), and an autofilter now lands on the sheet its range names. [Issue PHPOffice#5022](PHPOffice#5022) [PR PHPOffice#5023](PHPOffice#5023) - Support for Box and Whisker charts in Xlsx reader and writer. [Issue PHPOffice#3493](PHPOffice#3493) - Support for Windows Metafiles images (WMF, EMF and EMF+), using the `phpoffice/wmf` library: Xlsx Writer stores them as is, Ods, Xls, Html and Pdf Writers and comment backgrounds use a PNG rendering; Xlsx and Ods Writers can switch with `setConvertMetafilesToPng()` (new in `BaseWriter`), and `MemoryDrawing::fromString()` / `fromStream()` accept them. New methods `Drawing::isMetafile()` and `Drawing::getMetafileType()`, and new helper `Shared\Metafile`. - `Document\Properties::setLanguage()`: the language of a spreadsheet as a BCP 47 tag, written and read as `dc:language` in Xlsx and Ods; the Ods writer also gives it to the default cell style, where LibreOffice keeps a spreadsheet's language, as LibreOffice writes it (the Western, Asian or complex slot by script, and `style:rfc-language-tag` for a tag with more than a language and a country), and the Ods reader reads it from there when there is no `dc:language`. Html writes and reads it as the `lang` of the `html` element. [Issue PHPOffice#5040](PHPOffice#5040) [PR PHPOffice#5041](PHPOffice#5041) - Xlsx Writer and Reader: `Chart::setDescription()` is the alternative text of a chart, written as `descr` of the chart's frame and read back, and the frame takes the chart's name; LibreOffice exports it as `/Alt` of the chart in a tagged PDF. [Issue PHPOffice#5038](PHPOffice#5038) [PR PHPOffice#5039](PHPOffice#5039) - `BaseDrawing::setDecorative()` marks an image as decorative. Xlsx writes and reads it as Excel and LibreOffice do (`adec:decorative` in the image's `cNvPr`), Ods as LibreOffice does (`loext:decorative` in the frame's graphic style, which the writer now defines; the reader also takes ODF 1.4's `draw:decorative`); LibreOffice then leaves the image out of a tagged PDF as an artifact. Html writes and reads it as an empty `alt`. [Issue PHPOffice#5036](PHPOffice#5036) [PR PHPOffice#5037](PHPOffice#5037) - Xlsx Writer and Reader: the description of a header/footer image is its alternative text, `alt` on the VML shape as Excel writes it. [Issue PHPOffice#5056](PHPOffice#5056) [PR PHPOffice#5057](PHPOffice#5057) ### Changed - Update infrastructure for running samples in browser. [PR PHPOffice#5061](PHPOffice#5061) [PR PHPOffice#5068](PHPOffice#5068) - `phpoffice/wmf` is a new required dependency, used to render Windows Metafiles images. - The exception thrown for an unsupported comment background image now lists WMF and EMF among the supported types (`Drawing::UNSUPPORTED_IMAGE_TYPE_MESSAGE`). - Some Windows environments are added to CI unit tests. [PR PHPOffice#5053](PHPOffice#5053) ### Deprecated - Deprecate `_calculateFormulaValue` for `calculateFormulaValue`. [PR PHPOffice#4992](PHPOffice#4992) - Tcpdf V6 is now officially deprecated. We will continue to support it for now, but are considering dropping support with the next major PhpSpreadsheet release. ### Fixed - Xls Writer: a color matching a built-in palette entry above the custom range (e.g. `333333`) no longer makes the palette look full, so later custom colors are no longer written as black. [Issue PHPOffice#5065](PHPOffice#5065) [PR PHPOffice#5066](PHPOffice#5066) - Xlsx Reader and AgileEncryption parser reject a DOCTYPE or entity declaration in encrypted workbook metadata before parsing. [PR PHPOffice#5072](PHPOffice#5072) - `RIGHT()` returns all of the text when the number of characters requested is greater than its length. [PR PHPOffice#5044](PHPOffice#5044) - Comparison operators order values of different types as Excel does (numbers < text < FALSE < TRUE), so `=""<75` is FALSE. [PR PHPOffice#5004](PHPOffice#5004) - A "TRUE" or "FALSE" criterion matches logical values in COUNTIF, SUMIF, the database functions and the others sharing their criteria, as Excel does. [PR PHPOffice#5006](PHPOffice#5006) - OLE Writer now validates directory names, orders and colors sibling trees correctly, writes conformant CLSIDs and timestamps, and initializes unused directory-entry pointers to NOSTREAM. [PR PHPOffice#5033](PHPOffice#5033) - MIN and MAX return #VALUE! for non-numeric text typed as an argument, and count logical values and numeric text typed as an argument, as Excel (and SUM) do. [PR PHPOffice#5005](PHPOffice#5005) - `VALUE()` no longer treats product-like text such as `5V 2.1A - EU Wall Adaptor` as a date serial. [Issue PHPOffice#4996](PHPOffice#4996) [PR PHPOffice#4997](PHPOffice#4997) - Minor Xml Reader Improvements. [PR PHPOffice#4989](PHPOffice#4989) - Rename and change visibility of 2 Xls Writer properties. [PR PHPOffice#4995](PHPOffice#4995) - Documentation infrastructure tweaks. [PR PHPOffice#4994](PHPOffice#4994) [PR PHPOffice#4999](PHPOffice#4999) - Ods Writer writes a right-to-left sheet as `style:writing-mode="rl-tb"`, and Ods Reader reads it back; the direction was lost both ways. [Issue PHPOffice#5015](PHPOffice#5015) [PR PHPOffice#5016](PHPOffice#5016) - Ods Writer writes a link to another sheet as `#Sheet.A1`, as ODF and LibreOffice do, and Ods Reader reads that form back as `sheet://Sheet!A1`, so a Xlsx saved from it no longer gets a broken location. [Issue PHPOffice#5011](PHPOffice#5011) [PR PHPOffice#5012](PHPOffice#5012) - Ods Writer and Reader: the description of an image is written as `svg:desc` and read back, so that LibreOffice exports it as the alternative text of the figure. [Issue PHPOffice#5009](PHPOffice#5009) [PR PHPOffice#5010](PHPOffice#5010) - Ods Writer and Csv Writer (with `preferHyperlinkToLabel`) no longer add an empty hyperlink to every cell they write, which made a later Xlsx save throw "Invalid parameters passed." [Issue PHPOffice#5007](PHPOffice#5007) [PR PHPOffice#5008](PHPOffice#5008) [PR PHPOffice#5021](PHPOffice#5021) - Ods Writer keeps the hyperlink of a number, boolean or formula cell, and Ods Reader reads it back; only text cells had one. [Issue PHPOffice#5013](PHPOffice#5013) [PR PHPOffice#5014](PHPOffice#5014) - Don't iterate cell ranges on non-existent sheets. [Issue PHPOffice#5032](PHPOffice#5032) [PR PHPOffice#5035](PHPOffice#5035) - Xls Writer normalizes color strings to upper case and picks the next custom palette index from the highest index in use, so a color can no longer overwrite the palette slot of an earlier color (e.g. a font rendering in a fill color). [Issue PHPOffice#5019](PHPOffice#5019) [PR PHPOffice#5020](PHPOffice#5020) - Ods Reader reads the hyperlink LibreOffice keeps in the style of a number, boolean, date or formula cell (`style:hyperlink` in `style:table-cell-properties`), as it writes a link from a Xlsx file. [Issue PHPOffice#5017](PHPOffice#5017) [PR PHPOffice#5018](PHPOffice#5018) - `removeColumn()` no longer throws "Invalid column index 0" when it removes column A and every column up to the highest data column, e.g. `removeColumn('A')` on an empty sheet. [Issue PHPOffice#5049](PHPOffice#5049) [PR PHPOffice#5050](PHPOffice#5050) - `removeColumn()` and `removeRow()` take the removed columns/rows out of data validation ranges: a validation that lies only on them is deleted, and a range that ends on them shrinks, instead of covering the column/row that slides into their place. [Issue PHPOffice#5047](PHPOffice#5047) [PR PHPOffice#5048](PHPOffice#5048) - Minor cleanup in Ods Reader to fix test which was not working in Windows. [PR PHPOffice#5052](PHPOffice#5052) - A fraction number format writes an integer as a fraction when the format has no integer part, so 1 is `1/1` with `0/0`, and when the last numerator placeholder is 0, so 1 is `1 0/1` with `0 0/0`, as Excel does. [Issue PHPOffice#3625](PHPOffice#3625) [PR PHPOffice#5060](PHPOffice#5060) - Removing or inserting a column that shifts the header row of a table no longer throws `Worksheet no longer exists`. [Issue PHPOffice#5058](PHPOffice#5058) [PR PHPOffice#5059](PHPOffice#5059) - Branch pruning no longer throws "internal error" for an IF nested in the condition of another IF inside a pruned branch. [Issue PHPOffice#3755](PHPOffice#3755) [Issue PHPOffice#3790](PHPOffice#3790) [PR PHPOffice#5055](PHPOffice#5055) - Xls Writer no longer loses EMF and WMF images (they are written as PNG); the resulting file could not be read back (`Call to a member function getBlipType() on null`). [Issue PHPOffice#274](PHPOffice#274) - Xls Reader reads EMF and WMF pictures (as PNG `MemoryDrawing`); they were ignored. [Issue PHPOffice#274](PHPOffice#274) - Xlsx Writer declares WMF and EMF images as `image/x-wmf` and `image/x-emf` instead of `application/octet-stream`, and Ods Writer does the same in its manifest when it stores them as is. - Html and Pdf Writers display WMF and EMF images (as PNG) instead of an empty image. - Ods Writer no longer writes the formula text as the cell value when formulas are not pre-calculated. [Issue PHPOffice#5045](PHPOffice#5045) [PR PHPOffice#5046](PHPOffice#5046) - Xlsx Writer and Reader keep the custom formula of a table totals row (`Column::setTotalsRowFormula()`), written as `totalsRowFormula` with `totalsRowFunction="custom"`; before it was dropped. The totals row label, function (as `SUBTOTAL`) or formula of a column also sets its totals row cell when that cell is empty, so it no longer has to be set by hand. [Issue PHPOffice#5063](PHPOffice#5063) [PR PHPOffice#5064](PHPOffice#5064) - Avoid some breaks caused by new versions of libxml. [PR PHPOffice#5054](PHPOffice#5054) - `getDataValidation()` and `dataValidationExists()` no longer throw "Cell coordinate string can not be a range of cells" for a range once a validation on a range exists; a range gets the validation set on exactly that range, or a new one. [Issue PHPOffice#5073](PHPOffice#5073) [PR PHPOffice#5074](PHPOffice#5074) - Text formats containing `@` treat a backslash as an escape character, as Excel does, so `@\X` displays `Test` as `TestX` instead of `Test\X`; backslashes in the text itself are kept. [Issue PHPOffice#5069](PHPOffice#5069) [PR PHPOffice#5071](PHPOffice#5071)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is:
Checklist:
Why is this change needed?
RIGHTdrops characters from the start of the result whennum_charsis bigger than the text:The start offset
mb_strlen($value) - $charsgoes negative, andmb_substrthen counts it from the end of the string. Excel's docs say "If num_chars is greater than the length of text, RIGHT returns all of text", and LibreOffice does the same. This PR clamps the offset at 0.I added two cases to the RIGHT data provider: one ASCII and one multibyte, where the length is exactly one more than the text. Both fail without the fix. The TextData function tests pass, and php-cs-fixer, phpcs, and phpstan are clean on the changed file.