v5.0.0-rc1 Release Notes
Release Date: 16 October 2026
Note: The primary goals of this release were a new Bootstrap 5.3 interface, the removal of long-deprecated code and features, and a sweep of security and data-integrity fixes. This release removes the deprecated functions and class aliases, the old themes, PDF output and file check-in/check-out. Add-on modules and customizations that still depend on any of these will need to be updated before upgrading.
Downloading & Installing
The only official distribution site is Github. Check out the Installation page to get started.
Reporting Problems
For more information, support, or to discussion upcoming features, please visit our Support Forums.
Any and all issues discovered should be added to our our Issue Tracking System. Feature requests should be marked as such and not described as issues. Please remember to mark Feature Requests as requests and not bugs.
If you’re not familiar with submitting a bug, please read my post: How To Submit a Bug
New Features
- New Bootstrap 5.3 interface
- Bootstrap 5.3.8 is bundled with the application, so no CDN is needed
- NiceAdmin-style header, sidebar, colours and typography, using the bundled Nunito Sans and Poppins fonts and Bootstrap Icons
- New sign-in, sign-up and lost-password pages
- Layout tables replaced with Bootstrap markup in every module, the shared templates and the installer
- Bootstrap is now the only theme, so the per-user and system-wide style settings are gone
- Projects
- New “Tasks (All)” tab on the project view showing active and inactive tasks together in tree order (based on work by Klaus Buecher)
- Inactive tasks now have their own row colour and an entry in the task key
- Project budgets are shown on the project view again
- Tasks
- The “show inactive tasks” link on the Tasks list now works, as a “show all tasks” / “show active tasks” toggle (based on work by Klaus Buecher)
- Resources assigned on a task’s “Other resources” tab are saved again; nothing had saved them since v3.2 (based on work by Klaus Buecher)
- Files
- The Files list is grouped under project headings
- The Files list hides files from projects and tasks the user isn’t allowed to see
- New Owner and Category filters on the Files page, next to the Project filter. The owner filter also narrows the counts on the category tabs
- Custom fields
- Custom fields work on users
- Calendar (event) custom fields work again
Fixes/Bugs Closed
- Security
- Fixed stored and reflected XSS in the selector popup. Option labels are now escaped in every dropdown built with arraySelect() and in the project dropdown
- Public sign-up cleans the e-mail address before using it in the duplicate-address lookup (SQL injection)
- Translation files are read with a parser instead of eval() (#313)
- The translation editor only writes files for installed modules and languages; before, a crafted module name could write outside locales/
- The current password is checked with password_verify() when changing it, and saving a user no longer re-hashes the stored password (#386)
- The Active Sessions tab checks the session id before it reaches SQL
- Projects the user is denied are no longer counted in the company list or the project tabs
- Data integrity
- A refused delete no longer runs its cleanup. For example, a user who owned a project used to lose their login and preferences even though the delete was refused
- Deleting a project removes its placeholder task from the parent project and its custom field values, and records the delete in the history
- Deleting a user, event, forum, message or task log removes its custom field values, and only the deleted object’s own values
- Deleting a task removes its resource assignments. For a task with subtasks, the task’s own assignments and dependencies are now removed too
- Contacts are no longer saved with owner -1 when no one is logged in
- Users, permissions and LDAP
- Removed duplicate permission entries so User and Calendar permissions can be granted (#385)
- Users-module editors can save other users’ preferences (#385)
- Restored the “delete User” action on the user view (#385)
- Changed passwords are stored as typed and the real result is reported; the strength meter loads again (#386)
- LDAP: new users always get a contact and their password is hashed once; existing users without a contact get a placeholder (#320)
- The access log records logins again, and the logout controls show on the Active Sessions tab
- Logins are recorded as open until they end. Before, every login was stored as already ended, so logouts were never recorded and anyone who had ever logged in showed as “Online”. Logging out in one browser no longer closes the user’s other logins
- A session’s last-activity time is updated on every request, so active users are no longer logged out when the idle limit passes after login
- Projects and tasks
- Fixed the project Task Logs tab crashing on first visit and for projects with subprojects
- Fixed the project list being empty for users without full department rights
- “Update projects status” preselects the current status and shows the result
- Fixed a task’s Child Tasks tab always being empty
- Task reminders are sent again
- Tasks moved by a dependency keep their dates in UTC instead of shifting by the user’s offset (fix from Klaus Buecher)
- Re-parenting a task moves its subtasks along, so dynamic task dates roll up correctly (fix from Klaus Buecher)
- Moving a task to another project recalculates the old project’s dynamic tasks (fix from Klaus Buecher)
- Duplicating a file gives the copy the current user, date and its own history entry instead of the original’s. The same root cause meant
CTask::copy()/deepCopy()never updated the target project’s task count or gave the copies their own parent and position in the tree (reported by Klaus Buecher) - The filter checkboxes on the To Do Gantt chart work (#352)
- The project list’s “LP” column shows the problem icon for projects with a task log flagged as a problem again; it always showed “-“
- Moving a task to another project updates the old project’s task count, including when the move leaves it with no tasks
- Dates and time zones
w2p_Utilities_Date::convertTZ()returned the wrong time and often the wrong date (16:13 UTC became 08:13 for Indianapolis instead of 12:13, and a January date became today). This fixes the times in task reminder e-mails, the “today” marker on the Gantt charts and the month calendar, and the Tasks per User report’s date range
- Pagination and lists
- Page links keep the current view and sort order
- The Files list page links stay on the current project, company or task
- The company Files tab shows that company’s files
- Selecting a project on the Files page no longer turns off the category tabs, so project and category can be combined
- Resources
- Adding or editing a resource works on new installs. The installer left the Resources tables at an old module version, so saving failed with “Unknown column ‘resource_description’” and there were no resource types (migration 068)
- Reports
- Fixed the Project Statistics report crashing when there are no projects
- The Project Statistics report counts unassigned tasks correctly; its “No Assignee” row never went past 1
- The Task Logs reports apply their company filter, which was never read
- Report messages and values that were computed but never output are shown
- Database and upgrades
- Works with MySQL 8’s default sql_mode (ONLY_FULL_GROUP_BY is turned off for web2project’s connection)
- Migration errors are reported instead of silently dropped. A fresh install now completes with none
- Fixed migrations that errored on web2project databases or failed on strict servers (012, 033, 050/051, 056)
- Migration 056 keeps the version history
- Database version is now 68 (new migrations 063–068)
- PHP 8 and the error log
- A logged-in crawl of 257 pages now produces no PHP warnings or notices (421 before the final round of fixes): list tables, reports, ProjectDesigner, the ACL view, the role list, the Task Logs tab and task saves (
array_sum()on dependency lists) - Replaced the removed
$php_errormsgandmysql_get_client_info() - Fixed the LDAP authenticator’s method signature, a misspelled constant, a quoted preference name and a class/file name mismatch
- Fixed the translation editor crash on strings of 40 or more characters
- A logged-in crawl of 257 pages now produces no PHP warnings or notices (421 before the final round of fixes): list tables, reports, ProjectDesigner, the ACL view, the role list, the Task Logs tab and task saves (
Misc Changes/Improvements
- Removed
- PDF output (reports, Gantt charts and forums)
- File check-in/check-out (#376), file change e-mail notifications and the file version field
- The w2p-snowball and wps-redmond themes, and theme selection
- includes/deprecated_functions.php (66 functions) and the 37 deprecated class aliases (CAppUI, CDate, DBQuery, CTitleBlock and others). Third-party code still using them will now fail with undefined-function or undefined-class errors
- The remaining deprecated db_* helpers, replaced with w2p_Database_Connection
- Code cleanup
- PHPDoc cleaned up across all classes, modules and tests
- Removed commented-out PHP and JavaScript code and statements that could never run
- Fixed invalid HTML (duplicate and malformed attributes, unclosed elements, table/form nesting, deprecated tags) and made the directory-guard index files valid HTML5. No deprecated HTML tags (such as
<font>and<center>) remain in /modules
- Unit Tests
- The include tests now run as part of phpunit.xml and use the PHPUnit 11 API
- Removed tests for deleted deprecated methods and fixed broken assertions
- The phploc build target writes a real XML report
- Version set to 5.0.0 (Composer package 5.0)
Open/Known Issues
- The database layer - ADODB - is ancient and needs to be replaced. This is massive and touches every component.
- The date handling - PEAR Date - is ancient and needs to be updated to use Carbon.
- Names are still printed unescaped in some list tables and page titles (Companies, Projects and Tasks lists, calendar views, project and task views). This needs a central escaping pass.
- Uploaded files are stored inside the web root and protected only by an Apache 2.2-style
.htaccess(#394, #395). - Public sign-up has no captcha or rate limit, and it e-mails the plaintext password (#363).
- Session logout links are GET requests (admin only).
- Opening a file link while logged out gives a fatal error in
fileviewer.php. - The task tree joins user priorities and pins without the user, so the “U” column and the pin icon can show another user’s values, and ProjectDesigner doesn’t filter tasks by per-task permissions.
- The week view shades working days by column position, not by weekday.
- The placeholder task for an empty subproject gets the current date instead of the subproject’s dates.
- The unit test suite runs 509 tests with 7 errors and 15 failures.
System Metrics
There are some core metrics that may be of interest to the geekier among us. We generate these with phploc, using the phploc target in the unit_tests/build.xml file. Overall Code Metrics explains how to run it yourself.
- Lines of Code: 61617 (9450 of comments, 52167 of code)
- Cyclomatic Complexity:
- Per Class: 18.75 (min: 1.0, max: 252.0)
- Per Method: 2.49 (min: 1.0, max: 61.0)
- Per Line of Code: 0.26
- Interfaces: 2
- Traits: 0
- Classes: 132 (127 Concrete, 5 Abstract)
- Lines of Code/Class: 84
- Class Constants: 6
- Methods: 1603 (50 static, 1553 non-static)
- Public: 1480
- Protected: 113
- Private: 10
- Lines of Code/Method: 6
- Functions: 206
- Constants: 73