
UpyunFile v1.2 arrives about three months after v1.1, just as Typecho 1.3.0 has landed. The new Typecho release brings a broad set of internal changes, and those changes have broken compatibility for a number of plugins. UpyunFile was one of them: after upgrading to Typecho 1.3.0, the backend file management page threw errors and existing attachment URLs no longer rendered correctly. v1.2 addresses that breakage and also simplifies the plugin's configuration.
What Typecho 1.3.0 broke
Two symptoms showed up after the upgrade. The backend file management page reported an error and displayed attachment URLs incorrectly:
TypeError: UpyunFile_Plugin::attachmentHandle():
Argument #1 ($content) must be of type array, Typecho\Config given
...
Attachment links in posts also failed. Instead of a full CDN URL, the generated address lost its path:
https://cdn.example.com/
The fix in v1.2 uses several compatibility checks so the plugin can handle different Typecho data structures. It first looks for the attachment path inside the newer Config object. If that is absent, it checks for a direct path property. As a fallback for older stored data, it tries to unserialize the text field and read the path from the resulting array. The full URL is then built from that path and the configured domain.
public static function attachmentHandle(Typecho\Config $content) {
// 1. First check the Config object structure in newer versions
if (isset($content->attachment) && isset($content->attachment->path)) {
$path = $content->attachment->path;
}
// 2. Next, check for a direct path property
else if (isset($content->path)) {
$path = $content->path;
}
// 3. Finally, try unserializing from the text field (for older data)
else if (isset($content->text)) {
$attachment = @unserialize($content->text);
if (is_array($attachment) && isset($attachment['path'])) {
$path = $attachment['path'];
}
}
// Build the full URL
return Typecho_Common::url($path, $domain);
}
A file handle leak is closed
Code review also turned up a resource-management issue. In the old flow, the uploaded file handle was opened, passed to the Upyun write call, and then closed. If the write call threw an exception, the fclose call would not run.
Before:
$fh = fopen($uploadfile, 'rb');
$upyun->write($path, $fh);
// If write() throws an exception, fclose will not run
if (is_resource($fh)) {
fclose($fh);
}
v1.2 moves the cleanup into a finally block, so the handle is released whether the write succeeds or fails.
After:
$fh = fopen($uploadfile, 'rb');
try {
$upyun->write($path, $fh);
} finally {
// This runs whether or not an exception occurs
if (is_resource($fh)) {
fclose($fh);
}
}
One path setting instead of three modes
v1.1 offered three directory-structure modes:
- Custom structure:
/files/year/month/filename - Typecho structure:
/typecho/usr/uploads/year/month/filename - Compact structure:
/year/month/filename
In practice, almost all users picked the custom structure. The extra choices made the code more complex and the settings screen less clear, so v1.2 removes the mode selector entirely. There is now a single custom path field, defaulting to /files.
The final file path follows one fixed pattern:
{custom path}/{year}/{month}/{filename}
For example: /files/2026/04/example.jpg
This makes the settings page easier to understand, reduces configuration to one field, trims the code, and gives every upload a predictable location.
Release history
v1.2 (2026-04-02)
- Fixed Typecho 1.3.0 compatibility.
- Fixed incomplete URLs in backend file management.
- Fixed a file-handle resource leak risk.
- Simplified directory configuration by removing mode selection.
- Changed the default custom path to
/files. - Improved code comments for maintainability.
v1.1 (2026-01-09)
- Added custom directory structure support.
- Improved the backend settings interface and user experience.
Installing or upgrading
Requirements: Typecho 1.1 or newer (1.3.0+ recommended), PHP 7.0+, and a working Upyun account.
To upgrade from v1.1, back up the database and existing plugin settings first. Download the v1.2 package, replace the old plugin files while keeping the configuration, open the plugin settings and confirm the custom path, then upload a test file and check that its URL is generated correctly. If you prefer, you can also replace the existing Plugin.php with the version from GitHub.
For a fresh install, download the plugin archive, extract it into Typecho's usr/plugins directory as a folder named UpyunFile, and enable it under Console -> Plugins in the Typecho admin. Then open the plugin settings and fill in:
- Bound domain: the domain attached to the Upyun service, such as
https://cdn.example.com - Custom path: the base upload path, defaulting to
/files - Service name: the Upyun service name
- Operator: the Upyun operator account
- Password: the Upyun operator password
Save the settings to finish.
Settings overview
<table> <thead> <tr> <th>Setting</th> <th>Purpose</th> <th>Example</th> </tr> </thead> <tbody> <tr> <td>Image link rewriting</td> <td>Replaces image links in posts with CDN links</td> <td>Recommended on</td> </tr> <tr> <td>Bound domain</td> <td>Domain bound to the Upyun service</td> <td>https://cdn.example.com</td>
</tr>
<tr>
<td>Custom path</td>
<td>Base path for uploaded files</td>
<td>/files</td>
</tr>
<tr>
<td>Service name</td>
<td>Upyun service name</td>
<td>mybucket</td>
</tr>
<tr>
<td>Operator</td>
<td>Upyun operator account</td>
<td>operator</td>
</tr>
<tr>
<td>Password</td>
<td>Upyun operator password</td>
<td>password</td>
</tr>
</tbody>
</table>
Optional Upyun image processing can be enabled by creating a thumbnail version in the Upyun console and entering its name in the plugin settings. The thumbnail version name might be thumb or small, and the output format can be set to jpg, png, or webp. Images with a _nothumb suffix, such as example_nothumb.png, are excluded from this processing.
Token hotlink protection is also supported. Enable Token protection in the Upyun console, enter the key in the plugin settings, and set the signature expiry time in seconds.
Source and feedback
The project is available on GitHub Releases: https://github.com/NoEggEgg/UpyunFile
Bug reports can be filed as GitHub issues, and pull requests or improvement suggestions are welcome.
The plugin builds on earlier versions by codesee, ShadowySpirits, and liuran001. It also depends on Typecho and Upyun: - https://github.com/codesee/UpyunFile - https://github.com/ShadowySpirits/UpyunFile - https://github.com/liuran001/UpyunFile - https://typecho.org - https://www.upyun.com