A client’s OnPrintShop site went down after a VPS crash (disk full → DB corruption). We rebuilt everything on a new Rocky Linux server with cPanel, restored a 232-table MySQL database, verified 5k+ core files, and resolved all server-level issues (PHP 5.6 + ionCube 10.4.5, FastCGI, paths, themes, multistore config). The remaining blocker is vendor licensing: OnPrintShop’s ionCube-encoded core silently exits on new hardware until the vendor re-issues the license. Migration is 100% technically complete; go-live awaits the re-encoded files. Fix Broken Website
Context: What “Fix Broken Website” meant in this case
- Symptoms: total blank page, no fatal errors in
error_log. - Stack realities:
- OnPrintShop = ionCube-encoded PHP 5.6.
- Licensing tied to server fingerprint (IP/host/hardware).
- Some core & multistore plugin code is encoded and cannot run if the environment changes.
- Business pressure: this is a commercial storefront; downtime = lost orders + support load.
The 9 engineering moves (and why they matter)
1) Forensic triage & CMS identification
We scanned the recovered tree (232 top-level items) and confirmed OnPrintShop signatures in encoded headers. Result: quick certainty on the platform’s constraints, routes, and plugin layout (multistore, mailing, Twig, dompdf, PHPExcel, PHPMailer, etc.).
Why it matters: you can’t fix a broken website you don’t recognize—identifying ionCube early prevents days of chasing phantom PHP errors. Fix Broken Website
2) Rebuild the exact runtime (PHP 5.6 + ionCube 10.4.5)
Initial error proved encoding incompatibility with PHP 7+:
“file … was encoded for PHP 5.6 and cannot run under PHP 7.1 or later.”
We pinned the domain to ea-php56 via MultiPHP Manager and enabled ionCube Loader v10.4.5. A tiny probe confirmed loader presence:
if (function_exists('ioncube_loader_version')) echo ioncube_loader_version();
Why it matters: with ionCube apps, version parity is the fix.
3) Make deployment sane (shrink core from ~2GB+ → ~200MB)
Fix Broken Website – Uploading 75k+ media assets via browser is a trap. We wrote make_deploy_zips.bat to package only core app code, excluding heavy media caches and uploads, then moved media in batches later.
Why it matters: faster iterations = faster recovery. Fix Broken Website
4) Restore the data faithfully (232 tables, integrity verified)
- Recreated DB, imported dump, smoke-tested with a
mysqliprobe. - Verified key tables like
store_master,configuration_master,products,orders,users,site_language,site_theme.
Why it matters: you haven’t fixed a broken website if the data layer is a Schrödinger’s box.
5) Repair multistore configuration (the hidden 404)
store_master had empty URL and inactive status for the primary store. We updated:
UPDATE store_master
SET url='https://nonameprinting.com', status='1', themes='nonameprinting'
WHERE store_id=1;
Why it matters: OnPrintShop’s multistore checks domain mapping before rendering; mis-mapping = silent block before page build.
6) Prove file completeness (critical paths, classes, templates)
We scripted check_missing_files.php to assert presence of:
index.php,cms.php(encoded entry points)lib/*bootstrap,plugins/*(multistore & mailing),model/(358 files),services/,templates/, and theme skeleton
Why it matters: verifying the graph prevents wild goose chases over non-issues.
7) Capture runtime truth (output-buffered debug harness)
debug_index.php wrapped index.php to measure actual output and show notices:
- Only harmless
Undefined indexnotices appeared. - Execution consistently stopped right after loading
plugins/multistore/multistore_custom_function.php(ionCube-encoded).
Why it matters: when a protected app fails licensing, it often exits silently. Our harness proved it wasn’t PHP crashing—it was intentional. Fix Broken Website
8) Validate the hypothesis: the license check
- Multistore plugin files are ionCube-encoded.
- Disabling the plugin triggers hard includes elsewhere (cannot run without it).
- New server ≠ original fingerprint → license fails →
exit()path.
Why it matters: the root cause is licensing, not infra. That’s the difference between more patching vs. calling the vendor.
9) Operationalize & harden the new host
- PHP-FPM/FastCGI tuned; error reporting off in prod, logging on.
- Cache directories cleaned; media staged for phased upload.
- Security sweep (removed
phpinfo.php& scratch tools), perms normalized.
Why it matters: when the license re-issue lands, we want “upload → done,” not “upload → new fires.”
Key metrics (what we recovered and validated) Fix Broken Website
- Database: 232 tables restored cleanly.
- Codebase: 5k+ core files verified; 358 model files, 4 services, 2 themes of interest.
- Media: 75,793 master templates + 16,669 user images preserved (staged).
- Runtime: PHP 5.6.40 + ionCube 10.4.5 confirmed; Apache FastCGI.
- Turnaround: environment rebuilt and validated the same day; waiting on vendor license to render UI.
Root cause, plainly
- OnPrintShop ties encoded files to a server fingerprint (IP/host/hardware).
- After moving from the crashed VPS to a new Rocky Linux server, that fingerprint changed.
- The encoded multistore module passes through init and exits silently when validation fails.
If your goal is to fix a broken website here, infra alone isn’t sufficient—you need vendor-re-encoded files.
Business outcome (so far)
- Risk contained: data and configuration are safe, tested, and backed up.
- Time to recovery minimized: once the vendor re-issues the license, production can light up immediately—no new engineering required.
- Owner next step: send license re-issue request (we provided a ready-to-send template and required server details).
What we built to move fast next time
- Deep config audit tool (
deep_config_check.php) for store/URL/theme/language sanity. - Final pre-launch checklist (
final_check.php) to gate releases. - Media packaging automation to keep core deployments lean.
- Cache cleaner and missing-files checker to eliminate drift.
(All temporary diagnostic scripts are staged for removal before go-live.)

Lessons for engineers who have to fix a broken website like this
- Identify protection early. If ionCube is involved, align PHP + loader first.
- Chop deployments. Separate code from heavy media to iterate faster.
- Interrogate reality. A tiny buffered wrapper around
index.phpcan expose silent exits. - Map multistore. Blank URLs or inactive stores can look like “broken app.”
- Don’t fight the license. It’s by design. Work with the vendor; keep proof of purchase handy.
- Document fingerprints. Keep server/IP/license details in your runbook for future moves.
Appendix: Ops snippets (sanitized)
Check ionCube loader
<?php if (function_exists('ioncube_loader_version')) {
echo 'ionCube: ' . ioncube_loader_version();
} else {
echo 'ionCube loader missing';
} ?>
Sample php.ini deltas
display_errors = Off
log_errors = On
error_log = /home/<user>/public_html/error_log
memory_limit = 1024M
post_max_size = 64M
upload_max_filesize = 64M
SQL: fix primary store mapping
UPDATE store_master
SET url='https://nonameprinting.com', status='1', themes='nonameprinting'
WHERE store_id=1;