Tuesday, July 21st 2026 - 02:33AM :
It's done! - Clearing away 25 years of out-dated code
While writing this update, I appreciate only one or two people may even stumble upon it over the next year or so. And even then, they, that is to say, you reading this, may not care about what I've written below. Yet to me, it's significant. Let me explain...
A website is like a house- after a quarter century, it can start to fall into disrepair and needs urgent maintenance
Organic Metal proves it. This site in it's current form has now been online for 25 years and 8 months. So far as I know, I'm the only artist, and perhaps the only person in the world to have maintained a personal 'homepage' website for this long! Sure there may be one or two people who also kept their sites alive by renewing the domain name, and refreshing their web site with a completely new, updated redesign / aesthetic. But I, at least, have yet to find a personal site of this size that's maintained it's design since the year 2000.
I was on a mission to keep my site alive
As you can see from the previous entries on this page, I have continually made various tweaks and fixes to this little site of mine over the years. Sometimes I didn't have a choice. As the Web 1.0 era progressed to Web 2.0+, existing web-offerings became increasingly outdated. To the non-coders out there, you may not realise that the back-end code (HTMl, CSS, JavaScript, PHP and so on) that's used to write and display web pages has been through dozens of reiterations over the last few decades. Every 5 years or so, this would mean my website functionality might suddenly stop working, and needed a back-end update to get it displaying properly or performing as it should.
The trouble is, this site was built years before the advent of template websites like Squarespace, or content management platforms like WordPress. Every single update to adjust a font size, or add an image needed to be hand written in html, and sometimes manually applied across dozens of pages.
For those living in the modern world who can easily update all their online content via user-friendly social media platforms or templated systems, they have no idea how painstaking website updating used to be!
Even a website can hold personal meaning
After designing a new personal site in 2016 which uses my actual name- BenKrefta.com, Organic Metal was no longer necessary. I keep this site online as a sort of archive for myself and a few other fans to look back on. For me it represents years of my life- good years spent learning web design, maintaining the site, creating new art then adding it to the galleries, engaging with fellow amateur anime/game artists in the forums, and so on. I know Organic MEtal is ultimately just a small, personal site in a sea of websitses, but it's also something I'm proud of. Without it I wouldn't have gone on to get my first ever art commission, work as a professional web designer for many years, or write several how-to draw books which ended up selling nearly 1 million copies, globally and translated into multiple languages.
Using AI to audit
I've always been a fairly early adopter of new tech- hence why I was building websites back when I was 16/17 years old in the late 1990s, while most people barely knew what the internet was. And so now AI is the big thing. In around 2023 I started using ChatGPT - It blew me away. In 2024 I played with Midjourney, realising this would instantly put digital artists like myself out of a job! In 2026 I began Vibe coding with Claude. After building a few apps, I decided to finally fix up this site. Within the space of a few days, Claude AI and I managed to finish a couple of weeks of work. Work which, no doubt, would have taken me months alone to complete, since I've now become so rusty when it comes to coding. It audited the site, including the old Organic Metal Version 1 and helped execute a plan to bring it up to at least a more modern standard. This should help future proof the site for years to come.
What exactly did AI help change and modernise?
Below is a record of changes- mainly for me to look back on, but skimming through gives you an idea of how much was fixed:
The guiding requirements were preserved throughout:
- Retain the Organic Metal visual identity and legacy content formats. - Keep the file/folder content database rather than migrating it. - Keep the gallery, blog, updates, guestbook, comments, mailing-list and administration tools operational. - Avoid blanket escaping of trusted historical content that intentionally contains HTML. - Make security and compatibility changes without redesigning the public content. - Deploy and test on PHP 8.5.
### Initial PHP 8.5 triage and live regression fixes
1. Reviewed the site under PHP 7.4 first, then supported the move to PHP 8.5 once the user confirmed the server could be switched. 2. Investigated and repaired PHP 8.5 regressions reported from live testing, including blank artwork pages, broken individual blog pages, guestbook HTTP 500 responses and broken update pagination output. 3. Fixed update listing behaviour where page two showed blank/broken entries and attempted to load `images/icons/.gif`. 4. Restored blog comment, guestbook and artwork detail pages that emitted JavaScript errors when hidden form fields were absent. 5. Repaired administration mailing-list refresh/delete behaviour where the old inline `refreshme()` call was missing. 6. Replaced the broken legacy Zazzle/Society6/DesignByHumans sale-page content with the agreed "No Longer for Sale" wording and BenKrefta shop link. 7. Corrected contact/Q&A JavaScript issues that prevented old form handlers from working cleanly in the modern browser/PHP 8.5 environment.
### Administration cleanup and safer content editing
1. Added a dedicated administration page for deleting blog, update and art posts after the old `file_ex` file explorer was removed for security reasons. 2. Renamed the tool from **Delete Posts** to **Delete / Edit Blog, Update or Art Posts**. 3. Added expandable editing for listed content items. 4. Improved the delete/edit page table layout so header cells no longer inherited inappropriate horizontal-line backgrounds. 5. Fixed broken corner/table chrome on the delete/edit administration page to better match the rest of the admin area. 6. Linked the top admin title image back to `admin.php` on `delete_posts.php`, `om_mailing_list.php`, `artsubmit.php`, `update_blog.php` and `update_update.php`. 7. Replaced the removed insecure file explorer workflow with a narrower post-management task focused on known content types.
### Modern OM2 frame replacement work
1. Created the modern `pages/index_modern.htm` wrapper to imitate the old framed OM2 layout without the original multi-frame document. 2. Preserved the approximate 160px top header/nav, 157px illustrated left strip, main content scroll area and bottom/footer strip. 3. Tuned the top-main artwork sizing and positioning after live browser testing, including the final fixed background sizing required for the header image. 4. Moved compatible site redirects from the old frame route to the modern wrapper route while preserving incoming content URLs. 5. Kept the visual design deliberately unchanged during this phase; the work was layout preservation, not redesign.
### OrganicMetal1 persistent wrapper and audio player
1. Built an OrganicMetal1 wrapper so old pages sharing the same top navigation could sit inside a persistent shell. 2. Added the JavaScript audio button/player to the wrapper so audio can continue while navigating wrapped OrganicMetal1 pages. 3. Reworked OrganicMetal1 navigation so pages such as `linksanime.htm`, `links.htm`, `techniques.htm`, `projects.htm`, `guestbook.htm` and related tutorial/project pages load through the wrapper. 4. Removed duplicated old OrganicMetal1 top-navigation markup from the wrapped content pages instead of hiding it with CSS. 5. Adjusted affected absolute-positioned page elements upward after wrapper insertion/removal of duplicate navigation, including `content.htm`, `links.htm` and `techniques.htm`. 6. Reduced wrapper navigation cell/image spacing from 3px to 1px after visual testing. 7. Added a restrictive iframe page allow-list so the OrganicMetal1 wrapper only loads expected local `.htm`/`.html` content pages and the approved MVGC index target. 8. Renamed the OrganicMetal1 wrapper files from `index2.htm` to `index.htm` and `index2_content.htm` to `content.htm`. 9. Added redirect stubs so old OrganicMetal1 links to `index2.htm` and `index2_content.htm` continue to resolve to the new filenames. 10. Preserved the separate OM2 `pages/index2.htm?var1=` wrapper/redirect behaviour and avoided treating it as part of the OrganicMetal1 rename.
### OrganicMetal1 guestbook restoration
1. Rebuilt `OrganicMetal1/guestbook.htm` from the supplied legacy guestbook page and historical entry export. 2. Populated the restored static guestbook with the old entries while removing URLs from entry text as requested. 3. Removed the old guestbook input form. 4. Added the agreed notice explaining the guestbook closure and linking users to the newer Organic Metal 2.0 guestbook. 5. Added the OrganicMetal1 wrapper/footer treatment to the restored guestbook page, then removed the duplicate "Back to Organic Metal" footer link. 6. Corrected the guestbook title image positioning after wrapper integration.
### MVGC and legacy archive fixes
1. Corrected MVGC index navigation so its bottom image-map link under "previous" points back to the intended OrganicMetal1 home wrapper. 2. Added the OrganicMetal1-style wrapper/navigation to the MVGC index where requested, then removed the old duplicated top navigation rather than hiding it. 3. Fixed broken and malformed OrganicMetal1/MVGC email-link fragments left by old encoded `mailto:` markup. 4. Corrected MVGC Soul Calibur page markup where one entrant's comments had leaked into the wrong entry, separating the Voldo and Greatest Nightmare entries. 5. Discussed Windows-1252 versus UTF-8 conversion and retained the legacy character encoding to avoid damaging historical content. 6. Repaired OrganicMetal1 project-page banner alignment issues caused by inconsistent spacing around 200x40 banner images.
### Read-only UBB forum archive refinements
1. Replaced links to the old CGI/Perl UBB forum with the PHP read-only archive route. 2. Corrected forum archive links from `/ubb/forum_archive.php` to `/forum_archive.php`. 3. Linked the forum title/image from the interactive page to the new read-only forum archive. 4. Added public profile rendering while keeping private account details hidden. 5. Centred the read-only archive notices on forum and profile pages. 6. Added previous/next and page-number navigation for forum category pages where the underlying archived data allowed it. 7. Improved the category/topic page rendering so later pages more closely match page-one formatting, including topic icons, columns, last-post information, header/footer and underlined topic text. 8. Kept private/posting/login/moderation behaviour disabled.
### Dead-link review workflow and cleanup
1. Ran a site-wide dead-link audit as part of the cleanup process. 2. Generated a local manual review page so broken links could be quickly reviewed and marked for removal or replacement. 3. Fixed the review page when it initially rendered only the title/filter navigation with no entries. 4. Applied the user's first and second rounds of dead-link decisions from exported JSON files. 5. Removed links that remained undecided after the second pass, per the user's instruction, to avoid excessive manual review time. 6. Left a final live dead-link audit as an optional post-upload verification task.
### Miscellaneous legacy cleanup
1. Investigated incorrect gallery hit totals on `show_hits.php`. 2. Updated old MVGC/OrganicMetal1 cross-links while preserving intentionally separate root, MVGC and OrganicMetal1 destinations. 3. PHP linting used as a syntax check for PHP compatibility work. 4. Identified that the old audio loop pause was caused by the browser/player loop behaviour rather than the WAV file itself, leading to the wrapper-based audio approach. 5. Preserved the user's explicit "no redesign" requirement throughout the frame/wrapper/archive work.
## Phase 1: PHP stabilisation
### Goal
Make the existing public pages and administration tools reliable without changing their visual design or file formats.
### Runtime and request fixes
1. Added safe fallbacks for legacy server/request values, including `$phpself`, `$PHP_SELF` and the remote IP address. 2. Guarded request variables that previously assumed `$_GET` or `$_POST` keys always existed. 3. Converted paging values such as `skip` to non-negative integers. 4. Constrained artwork categories, entry folder names and other path components to expected alphanumeric, underscore and hyphen formats. 5. Constrained comment and guestbook deletion filenames to their timestamp-based naming conventions. 6. Corrected unquoted date-array keys such as `$today[mon]` to PHP-compatible quoted keys. 7. Replaced obsolete artwork upload globals with `$_FILES`. 8. Corrected artwork `description.txt` writes so they use the selected category and newly created artwork folder. 9. Corrected comment, guestbook, blog and update save strings that previously relied on broken variable-variable interpolation. 10. Corrected JavaScript cookie parsing from the invalid `.explode()` call to `.split()`. 11. Corrected preview date/time construction that relied on undefined variables. 12. Added collision detection for timestamp-named artwork/content folders so an existing entry is not silently overwritten. 13. Repaired guestbook avatar output so valid avatar images render again. 14. Added safer handling for missing files/directories and malformed legacy content in active rendering paths.
### Gallery and content fixes
1. Reworked `displaythumbs.php` so `displaynew()` accumulates every qualifying artwork entry instead of only the final scanned entry. 2. Ensured gallery directory scans close handles and tolerate absent/invalid directories. 3. Restored individual artwork pages that had produced HTTP 500 errors after the PHP upgrade. 4. Restored individual blog pages and the guestbook after PHP 8.5 HTTP 500 regressions. 5. Preserved the existing artwork, blog, update, comment and guestbook text-file layouts.
### Hosting and public entry points
1. Replaced the web host placeholder behaviour with the real Organic Metal site. 2. Defined an explicit `DirectoryIndex` order in `.htaccess`. 3. Preserved old URLs and content locations while fixing the active entry route.
### Validation completed
The user completed live runtime and form testing, including the public forms and administration tools. PHP lint was run locally with PHP 8.5. The repaired gallery, artwork, blog and guestbook routes were also checked after deployment.
---
## Phase 2: safety hardening
### Goal
Reduce the risk from public write endpoints, administrator authentication, uploads and filesystem editing while preserving legacy behaviour.
### Shared validation and escaping
1. Added `om_clean_path_part()` for safe path components. 2. Added `om_clean_text_filename()` for timestamped text filenames. 3. Added `om_get_int()` for guarded non-negative integers. 4. Added `om_escape()` for context-appropriate HTML escaping using the site’s legacy character set. 5. Added validated helpers for public email addresses, HTTP/HTTPS URLs, colour values and avatar filenames. 6. Restricted public comment HTML to attribute-free `b`, `i`, `u` and `br` tags. 7. Preserved trusted legacy blog, artwork and update HTML instead of applying destructive blanket escaping. 8. Restricted contact-form redirect destinations to local/approved destinations. 9. Restricted the IP-ban tool to valid IPv4 input. 10. Changed ban handling to a server-side HTTP redirect where output timing permits it.
### CSRF and same-origin protection
1. Added cryptographically random session CSRF tokens. 2. Used `hash_equals()` for token comparison. 3. Return HTTP 403 for invalid or expired protected requests. 4. Added CSRF fields/checks to artwork upload, blog/update posting, comment deletion, guestbook deletion, post editing/deletion, IP banning and logout. 5. Added a same-origin check for POST requests as an additional cross-site submission safeguard.
### Administrator authentication and sessions
1. Added per-IP administrator login throttling. 2. Three failed password attempts trigger a 15-minute cooldown. 3. Login failure state is stored outside public content using hashed state filenames and locked writes. 4. Restricted administration routes to visitors. 5. Regenerate the session ID after successful authentication. 6. Added `HttpOnly`, `SameSite=Strict` and conditional `Secure` session-cookie settings. 7. Added a day absolute administrator session lifetime. 8. Added an explicit CSRF-protected logout action. 9. Positioned the logout button at the bottom centre of the administration page as requested.
### Public-form spam controls
1. Added per-form, per-session tokens to the artwork comment, blog comment and guestbook forms. 2. Added a visually hidden honeypot field. 3. Reject submissions completed in seconds. 4. Reject form tokens older than two hours. 5. Limit each IP address to three submissions per form in any 15-minute period. 6. Return HTTP 429 when the form-specific rate limit is reached. 7. Store rate-limit records with locked writes in the protected directory.
### Upload and filesystem controls
1. Validate artwork upload extensions against an explicit allow-list. 2. Validate detected image MIME type using image metadata, rather than trusting the filename alone. 3. Require successful HTTP-upload status and `is_uploaded_file()`. 4. Sanitize generated thumbnail names. 5. Confirm selected artwork categories exist before creating content. 6. Prevent timestamp collisions from overwriting an existing artwork folder. 7. Reworked post edit/delete path construction to accept only known content types, categories and timestamp entry names. 8. Verify resolved delete/edit targets remain inside the expected content root. 9. Use constrained recursive deletion rather than accepting an arbitrary supplied path.
### Explicit user decisions
---
## Phase 3: PHP 8.x / PHP 8.5 compatibility
### Goal
Make the active website and bundled PHP tools run cleanly on PHP 8.5.
### Compatibility changes
1. Replaced legacy short PHP opening tags with `2. Quoted array keys that PHP 8 treats as undefined constants. 3. Guarded undefined `$_GET`, `$_POST`, `$_SERVER` and session values. 4. Removed obsolete `$HTTP_POST_FILES` usage. 5. Replaced fragile variable-variable string interpolation with direct variables. 6. Added compatibility fallbacks for old template names such as `$PHP_SELF`. 7. Prevented unsafe `count()`, file and directory assumptions in high-value routes. 8. Corrected syntax/runtime issues responsible for PHP 8.5 HTTP 500 errors. 9. Fixed warning-prone content reads and scans where legacy files can be absent or malformed. 10. Retained the Windows-1252/ISO-8859-1 behaviour required by historical content rather than performing a risky bulk encoding conversion.
### Validation completed
1. Installed/used local PHP 8.5. 2. Ran recursive syntax lint across the PHP files. 3. Corrected every reported syntax failure from the lint result supplied by the user. 4. Re-ran lint after subsequent security, sitemap, analytics and forum changes. 5. Confirmed runtime/forms on the published PHP 8.5 host.
### Residual compatibility note
Very old static HTML, CGI/Perl forum data, backups and archive assets remain historical material. They are not converted into modern PHP applications. The public forum is exposed through a safe read-only PHP renderer rather than executing the old UBB posting software.
---
## Phase 4: modern layout without legacy framesets
### Goal
Preserve the approximately 160-pixel header, 157-pixel illustrated left strip, scrolling content area, bottom strip and original Organic Metal styling without relying on the original multi-frame document.
### Changes completed
1. Created `pages/index_modern.htm` as the active modern wrapper. 2. Recreated the surrounding layout and positioning with modern HTML/CSS. 3. Preserved the original header/navigation imagery, left illustration, content region and footer appearance. 4. Added `pages/index2.htm` as a compatibility redirect to the modern wrapper. 5. Preserved incoming query strings and fragments during that redirect. 6. Updated shared JavaScript frame-routing behaviour to target `pages/index_modern.htm` over HTTPS. 7. Preserved navigation targeting and current content behaviour with one named content iframe (`omContentFrame`). 8. Added same-origin content-frame handling so internal links and page state continue to work in the wrapper.
### Deliberately retained items
1. `pages/index.htm` remains as an inactive legacy frameset document. 2. `pages/index2_frameset_backup.htm` remains as a backup of the old layout. 3. The active wrapper still has one content iframe. Therefore the original multi-frame architecture is removed from the active route, but the site is not strictly iframe-free. 4. Comment preview iframes and Vimeo media iframes are functional embeds and are unrelated to the retired layout frameset. 5. Some OrganicMetal1 archive portfolio pages retain their historical iframe behaviour.
### Final position
The practical Phase 4 objective—replacing the active top/left/main/bottom frameset while preserving the look—has been achieved. Removing the remaining content iframe would require a deeper navigation/content migration and was not considered necessary for this update.
---
## Phase 5: content and administration maintainability
### Goal
Make future maintenance safer while retaining the file-based CMS.
### Changes completed
1. Created `MAINTENANCE.md` documenting the project purpose, PHP target and deployment process. 2. Documented the artwork directory structure and `description.txt` line layout. 3. Documented blog, update, comment and guestbook folder/file naming conventions. 4. Documented security-state storage and directory write requirements. 5. Added the complete local PHP lint command. 6. Added a manual deployment and rollback checklist. 7. Documented how a future transactional artwork upload could be implemented safely. 8. Added a safer administration tool for listing, reading, editing and deleting blog/update/artwork content. 9. Added content validation before critical writes. 10. Added collision handling so timestamp duplicates fail clearly. 11. Added clearer success/error output in affected administration paths. 12. Reviewed reported orphaned/unreferenced files manually; the user confirmed that all relevant findings were handled. 13. Retained manual FTP backups by explicit user choice instead of building an automated export tool.
### Clarification about the content checker
A read-only content-integrity checker existed during the work and was used to identify malformed or possibly orphaned content. It was subsequently removed after the review was completed, along with stale links/restrictions referring to it. `MAINTENANCE.md` still contains an historical reference to **Check Content Integrity**; that instruction should be treated as obsolete unless the checker is restored later.
### Deferred optional improvements
1. A transactional temporary-directory/atomic-rename artwork upload remains documented but not implemented. 2. A database migration was neither required nor desired. 3. Automated backup/export and restore tooling was declined in favour of manual FTP copies. 4. Full centralisation of every legacy content read/write routine was not required for this stabilisation project.
---
## Phase 6: SEO, analytics and deployment hygiene
### HTTPS and preferred-host handling
1. Added permanent redirects to the preferred origin: `https://www.organicmetal.co.uk`. 2. Redirect non-HTTPS and non-`www` requests while retaining the original request path/query. 3. Replaced hundreds of internal `http://www.organicmetal.co.uk` references with HTTPS equivalents. 4. Added an explicit `DirectoryIndex` order. 5. Retained custom error-document behaviour.
### Canonical URLs
1. Added a shared canonical URL builder. 2. Normalised the home/default routes to `https://www.organicmetal.co.uk/`. 3. Retained only meaningful parameters for individual artwork and blog canonicals. 4. Retained valid pagination parameters on listing pages. 5. Added canonical tags to the main public PHP routes.
### Robots and sitemap
1. Replaced the missing/obsolete compressed sitemap reference with `https://www.organicmetal.co.uk/sitemap.php`. 2. Expanded `robots.txt` exclusions for administration, write endpoints, configuration, runtime security state and private/maintenance material. 3. Created a dynamic XML sitemap with valid XML escaping and modification dates. 4. Added core public pages and selected human-sitemap pages. 5. Added every valid individual artwork page discovered from the artwork folders. 6. Added every valid individual blog entry discovered from the blog folders. 7. Added 462 public MVGC HTML pages. 8. Added 35 curated OrganicMetal1 entry/content/tutorial pages while excluding duplicate frame helpers and hundreds of low-value image-detail popups. 9. Added 1,921 public read-only forum topic URLs. 10. Explicitly excluded private Forum20 areas, forum member data, templates, search caches, administration scripts and raw internal CGI routes. 11. Excluded Hothouse at the user’s request. 12. The validated expanded sitemap contained 2,692 URLs at completion. 13. Added `X-Robots-Tag: noindex` to the sitemap response itself while allowing its listed URLs to be discovered.
### Read-only forum archive
1. Preserved the old UBB content through `forum_archive.php` without executing the legacy posting/login/moderation CGI application. 2. Rewrote historical forum links into safe read-only archive URLs. 3. Added public forum/category/topic rendering and pagination. 4. Kept private forums unavailable. 5. Disabled posting, registration, login, private messages and moderation actions. 6. Repaired public avatar/resource URL handling in archive output. 7. Included public topics in the dynamic sitemap.
### Google Analytics 4
1. Removed obsolete `ga.js`, `_gaq` and `UA-` tracking references. 2. Added the current Google tag using GA4 Measurement ID `G-SP83WG4BS8`. 3. Added the shared tag to current PHP pages, including individual artwork and blog pages. 4. Added the tag directly to all 462 MVGC static HTML pages. 5. Added the tag directly to the 35 sitemap-selected OrganicMetal1 HTML pages. 6. Added the tag dynamically to public read-only forum archive output. 7. Verified all selected static pages contain the tag and Hothouse contains none. 8. Analytics loads immediately. Cookie-consent gating was discussed and intentionally declined by the user.
### SEO review and archive optimisation
1. Created `seo_archive_review.php` to provide a central review interface for pages, artwork descriptions and images. 2. Added editable suggestions for page titles, meta descriptions, H1 headings, main text and image alt text. 3. Corrected spelling, grammar and broken character encoding in suggested artwork descriptions while preserving Ben's original wording and tone. 4. Visually reviewed archive artwork and wrote descriptive alt text for images, including recognisable characters and relevant visual details. 5. Applied approved review data to the website files and corrected artwork-page rendering issues involving headings, line breaks and emoticon codes. 6. Improved the homepage introduction including replacing the misleading live date with a continuously calculated statement. 7. Added canonical host redirects to consolidate HTTP, HTTPS, www and non-www versions under `https://www.organicmetal.co.uk`. 8. Added or updated redirects and internal links for obsolete duplicate pages, including directing `info_questionsanswers.htm` to `info_qa.htm`. 9. Added archive-aware indexing controls for broken or low-value legacy pages while retaining the historical files. 10. Generated and submitted an updated sitemap to help search engines discover the preserved archive and its improved page metadata.
---
Final conclusion
It wasn't perfect, but I was seriously impressed with how well AI coped with these site updates. It seems obvious that most classically trained light to middle-weight coders, artists, writers, animators, musicians, translators will be out of work within the next decade providing AI is being leveraged properly. For every 100 professionals, you'll only need a dozen prompters and AI care-takers to manage the work-load. The pace of change is terrifying for those around now to see it.
But, as I half-jokingly said to my brother recently, we might as well have fun using AI until it kills us!
For me, it's meant having the ability to keep my tiny slice of the internet alive in form of this archived website.
|