Notas da versão 4.2.0: 2 novidades 21 melhorias 51 correções 3 reforços de segurança
Novidade
- Added define( 'SPEAKER_RESET_KEYS', true ); for wp-config.php as a last-resort way to clear both Google keys when a broken vendor directory stops the site from rendering wp-admin at all. The check runs before the Google libraries are loaded, so it still works in that situation
- Added the speaker_input_mode filter to override how the content is sent to Google: as SSML, as Chirp markup or as plain text
Melhoria
- Technical error messages are no longer shown in the admin area. Problems you can solve yourself are now explained in plain words: a missing or revoked Google key, the Text-to-Speech API not being enabled for your project, a reached quota or inactive billing, the server not being able to reach Google, an out of date security certificate, a missing PHP extension, a PHP memory limit that is too low, a conflicting library from another plugin, an unwritable uploads folder, a part length that…
- Anything that is not one of those is now reported as a short notice pointing at the PHP error log, instead of printing the exception text, file path and line number on the page. The full technical detail is always written to the error log, and is shown on screen only when WP_DEBUG is enabled
- Error notices in the admin area are now shown only to administrators
- The Voice tab no longer embeds the raw HTML error page returned by Google when the key or the API is not correct
- Replaced the User-Agent check on the internal content-parsing template with a signed, short-lived token. The old check could be spoofed and was skipped entirely when WP_DEBUG was on
- The Google libraries are no longer loaded on front-end page views. They are loaded only for the admin area, AJAX, cron and REST requests, which cuts memory use on every visitor request
- Audio metadata is now cached in post meta instead of being re-read from the file on every call. Generating the podcast feed no longer re-parses every episode several times
- The rendered voice list is now cached, instead of being rebuilt on every settings page view
- The admin notice check no longer reads the entire audio folder listing on every admin page load
- Schema markup is now built with the WordPress JSON encoder instead of HTML escaping
- Voice avatars in the Voice tab no longer change on every page load
- Dates in the metabox and the dashboard widget now follow the site timezone and language
- On PHP below 8.1 the plugin now refuses to load the PHP 8 libraries and shows the notice about the Speaker PHP7 add-on, instead of failing with a blank page
- Audio file names generated from the [title], [name] and [author] patterns are now sanitized, so spaces become hyphens and unsafe characters are removed. Audio generated by earlier versions is still found under its original name and keeps playing: nothing has to be regenerated after updating. Only newly generated audio uses the new naming, and the old file for a post is cleaned up once that post is generated again
- Updated the Audio File Name field description, which said spaces were kept in file names
- Removed unused code from the speech generation class: the WAV joining helper, the HTML repair helper, the deprecated SSML support check and a duplicate page template callback
- The Google API key is now passed to the Text-to-Speech client directly instead of through a patch of the bundled Google Auth library, so updating the libraries can no longer break the authentication with "Could not construct ApplicationDefaultCredentials"
- Updated the Google Cloud Text-to-Speech library to v2.8, required by the Chirp 3: HD pause markup
- Updated the Google API Client library to v2.19
- Raised the minimum PHP version for the main plugin to 8.1. Sites on PHP 7.4 keep working through the Speaker PHP7 add-on
- Removed the unused Google API service classes from the bundled libraries, keeping only Google Drive. The plugin package is back under 7 MB
Correção
- Fixed voice previews that stopped playing everywhere: in the Voice settings tab, in the post metabox and in the Speech Template editor. Google moved its voice samples to a new address, and the old one started returning a web page instead of audio. Previews now use the new location, which also covers Chirp 3: HD, Chirp HD, Studio, News and Polyglot voices. When Google has no sample for a voice, the Voice tab now says so instead of showing a player that does nothing
- Fixed the Speaker and Playback analytics columns on the WooCommerce Products list (and any other list where a plugin sets fixed column widths): the columns collapsed to a few pixels wide and their headers overlapped the neighbouring "Product brands" column. The columns now reserve their own width, and the cell content is laid out inside the cell instead of turning the cell itself into a flex box
- Fixed the player on posts split with the "Page break" block: with pretty permalinks every page of the post played the audio of the first page. Each page now plays its own audio file
- Fixed the Speech Template Editor hanging on an endless preloader. The page preview is now always opened on the same address as the admin area (previously it failed when the site address differed from the WordPress address by https, www or port), the editor allows the preview to be embedded even when a security plugin sends X-Frame-Options, drafts are previewed correctly, and when the preview still cannot be loaded the editor shows what went wrong and a link to open the page instead of spinning…
- Fixed a flood of "Trying to access array offset on value of type null in .../protobuf/.../RepeatedField.php" warnings, followed by "headers already sent", on sites updated from a previous version. The cached list of Google voices was stored as raw Google library objects, which no longer unserialize correctly after the library update. The list is now cached in a plugin-owned format, a stale cache is detected and discarded automatically, and the old cache entry is removed
- Fixed the "array_key_exists: Argument #1 ($key) must be a valid array offset type" error in the admin area, caused by the language code returned by Google being handled as a plain array
- Fixed the Google Drive authorization callback accepting an authorization code from any source. The callback now verifies a one-time state value and requires an administrator, so the site's audio uploads can no longer be redirected to someone else's Drive
- Fixed the audio generation, audio deletion and Speech Template AJAX endpoints checking only a nonce. Contributor-level users could delete audio from any post, run up the Google Text-to-Speech bill and rewrite site-wide Speech Templates. All four endpoints now check user capabilities
- Fixed generated audio file names not being sanitized, so a post title containing slashes could write files outside the uploads folder
- Fixed the player icon and share icon settings being able to read any file on the server into the page
- Fixed the plugin disabling TLS certificate verification for every HTTP request made by WordPress, including requests from the core and from other plugins
- Fixed PHP exception details, including absolute server paths and line numbers, being shown to visitors and non-administrators
- Fixed the public analytics endpoint accepting any post ID, which allowed anonymous visitors to inflate playback counters and add meta rows to arbitrary posts
- Fixed the author voice field on the user profile being saved without validation or sanitization
- Fixed plugin settings being saved without a sanitize callback. Custom CSS, feed templates, Schema markup and regular expression fields are preserved as before
- Fixed Custom CSS and the player colour and size settings being written into the page without sanitization
- Fixed the tag attribute of the [speaker-mute] shortcode allowing arbitrary markup. It is now limited to a list of safe tag names
- Fixed a fatal error on every page containing a player when the URL carried a non-numeric page parameter
- Fixed the podcast feed being cut off at the "posts per page" setting, so only the 10 most recent episodes reached Apple Podcasts and Spotify
- Fixed the podcast feed publication date not following RFC 822, which made strict podcast clients mis-order or reject episodes
- Fixed every page of a multipage post sharing one GUID in the podcast feed, so clients collapsed them into a single episode
- Fixed the feed becoming invalid XML when the site title or tagline contained an ampersand or an angle bracket, and fixed double-encoded episode titles
- Fixed episode enclosure URLs losing their query string, and fixed empty type and length attributes for posts using a custom audio file
- Fixed the default podcast template missing the iTunes category, type and summary tags that Apple requires
- Fixed the podcast XML file being written to a path guessed from the plugin folder layout, with no error handling. It now uses the WordPress filesystem API
- Fixed the dashboard widget appearing when analytics was turned off, quota percentages being shown 100 times too small, and the used quota being counted in bytes instead of characters
- Fixed duplicate voices in the metabox voice list, and a fatal error when the cached voice list had expired
- Fixed the Voice tab saving the language setting into an option that no longer exists
- Fixed the width and spell-check attributes never being applied to the Voice and Schema tab controls
- Fixed the player style not carrying over for sites upgrading from the "rounded" style
- Fixed the analytics columns setting defaulting to a column that does not exist
- Fixed the supported post types setting never falling back to its Posts and Pages default
- Fixed sentences longer than the part length limit being silently dropped from the generated audio. They are now split instead
- Fixed pause markup being inserted inside decimal numbers, abbreviations and tag attributes, which produced invalid SSML and could fail the whole request
- Fixed long custom text elements in a Speech Template being read out twice
- Fixed soft hyphens being read out loud
- Fixed audio generation reporting success when it had failed, and fixed multipage posts reporting only the status of the last page
- Fixed the audio URL and duration saved for pages of a multipage post pointing at the first page
- Fixed a failed content fetch aborting the whole post save with a raw JSON response in the editor
- Fixed Media Library entries for generated audio storing HTML-escaped titles, a hardcoded author and no attachment metadata
- Fixed analytics counters losing plays when several visitors listened at once, a negative bounce rate with looping enabled, and lost precision in the play rate
- Fixed the "Google Drive token is saved" notice appearing on any admin URL carrying a scope parameter
- Fixed an unclosed tag and an unescaped value in the post list download column
- Fixed uninstall leaving behind any plugin option whose value was empty or zero
- Fixed an error when a multilingual language code was passed as an array
- Fixed possible fatal errors when the Google Drive client could not be built, and fixed the Drive client checking the Text-to-Speech key instead of the Drive key
- Fixed the pause shortcode and all other SSML shortcodes being silently dropped with Chirp 3: HD voices: pauses are now sent as Chirp pause markup
- Fixed the settings page rendering without styles when the Google API key is missing or malformed. The error is now logged and the key upload form is shown instead
- Fixed HTML entities being read out loud ("Tom & Jerry") with Chirp and Journey voices
- Fixed paragraphs, list items and table cells running into each other with Chirp and Journey voices
- Fixed the phoneme shortcode being stripped before the synthesis request
Segurança
- Fixed a vulnerability that let any visitor erase the site's Google Text-to-Speech API key by requesting a URL. Resetting a key now requires an administrator and a signed link
- Fixed the same vulnerability for the Google Drive storage key
- Updated the Firebase PHP-JWT library to v7.1, which resolves the CVE-2025-45769 security advisory