Download the PHP package ramon/mybb-migrator without Composer

On this page you can find all versions of the php package ramon/mybb-migrator. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package mybb-migrator

MyBB Migrator (ramon/mybb-migrator)

A faithful, ID-preserving migrator from MyBB (with the DVZ Hash password plugin) to Flarum 2. It is a Flarum extension that ships a suite of php flarum mybb:* console commands. Unlike a generic importer, it keeps the original primary keys (uid -> users.id, tid -> discussions.id, pid -> posts.id, fid -> tags.id, custom gid -> groups.id) so every cross-reference (likes, mentions, quotes, polls, PMs, trader feedback) lands on the right row.

What it migrates:


1. Requirements

Requirement Notes
PHP ^8.3 with ext-pdo (MySQL) enabled — used to read the MyBB DB
Flarum ^2.0 target install
MySQL/MariaDB both the MyBB source DB and the Flarum DB
CLI access the migration is run entirely through php flarum mybb:*

Target Flarum extensions

These must be installed and enabled before migrating, because the commands write directly into their tables:

Extension Used for
flarum/tags forums -> tags (required — content depends on tags)
flarum/likes mybb:likes
flarum/mentions user/post mentions extracted by mybb:content
flarum/subscriptions mybb:subscriptions
flarum/suspend banned users -> suspended
flarum/sticky sticky threads -> is_sticky
flarum/lock closed threads -> is_locked
flarum/approval soft-deleted / unapproved state
flarum/bbcode + flarum/markdown rendering of converted BBCode
fof/byobu private messages
fof/polls polls + votes
fof/upload attachments / uploaded files
huseyinfiliz/traderfeedback iTrader + Community Reviews
michaelbelgium/mybb-to-flarum optional companion — see below

About michaelbelgium/mybb-to-flarum

You do not need it at all. This extension has no admin settings page of its own — the MyBB database credentials are supplied via CLI flags and the extension stores them itself (see Configuration below). All data logic lives in this extension's own mybb:* commands.

The companion extension is only useful for copying the physical files (avatars / attachments) into public/assets/..., since this migrator only backfills users.avatar_url and references attachments — it does not move files. If you copy those files manually, you can skip the companion entirely.

Note on settings keys: the credentials are stored under the keys mybb_host, mybb_port, mybb_user, mybb_password, mybb_db, mybb_prefix. These happen to be the same keys the companion extension uses, so if it is installed, filling its admin page is just an alternative way to set the same values. The values are written by this extension's commands regardless — no companion required.


2. Installation

Enable the extension in the Admin panel. Make sure all target extensions above are installed and enabled first.


2.1. Quick start (full command sequence)

Copy-paste, edit the credentials on the first line, and run from the Flarum root (d:\laragon\www\flarum). Only the first command carries the connection flags — every later command reuses them from settings.

Tip — stop on first error. Wrap Phases 1–2 in a loop so a failure halts the whole run (each step depends on the previous one):

Then run the Phase 3 clean-up passes you need (see §4). Linux/macOS users: replace ^/backtick line breaks with \ and run under bash.


3. Configuration (MyBB database connection)

This extension has no admin UI. You point it at the MyBB database entirely through CLI flags. Each command resolves the connection in this priority order:

  1. the CLI flag you pass (--host, -u, -p, ...);
  2. otherwise the value previously stored in Flarum settings;
  3. otherwise a built-in default.

After resolving, it writes the values back to settings — so you pass the flags once (on the very first command) and every later command only needs --force. No settings page, no companion extension required.

Every command shares these options:

In this project the live MyBB tables used the prefix dfsmybb_.

Example (first command sets and stores the connection):

After that, later commands can be run with just --force.


4. Migration order

All write commands require --force. Most support --dry-run to preview. Run from the Flarum root: php flarum <command>.

Recommended order at a glance

The order below is not arbitrary — it is the exact sequence enforced by the ID/foreign-key dependencies between MyBB and Flarum. Run the phases top to bottom.

Phase # Command What it does
0 (optional) — mybb:wipe clears Flarum content for a clean re-run
1 — Core 1 mybb:groups custom groups (gid≥8), IDs preserved
2 mybb:users users (uid=id), captures passwords, maps groups
3 mybb:avatars backfills users.avatar_url
4 mybb:tags forums → tags (fid=id) + hierarchy
5 mybb:content threads → discussions (tid=id), posts (pid=id), BBCode→Flarum, mentions
6 mybb:likes post likes
7 mybb:permissions default + custom-group permissions
8 mybb:forum-perms per-forum view restrictions → tag perms
2 — Secondary 9 mybb:subscriptions thread/forum follows
10 mybb:messages private messages (fof/byobu)
11 mybb:polls polls + votes (fof/polls)
12 mybb:trade-feedback iTrader (traderfeedback)
13 mybb:reviews Community Reviews (traderfeedback)
14 mybb:make-admin promote your own account to Admin
3 — Cleanup — mybb:fix-* / mybb:revert-* data-specific fidelity passes — run only what you need

⚠️ Golden rule: if any command fails, stop and fix it before continuing — each step depends on the previous one. Always back up the Flarum database before you start, and use --dry-run first wherever it is available.

Before you start, confirm:

Phase 0 — Preparation

Phase 1 — Core data (order matters — IDs/foreign keys depend on it)

Why this order:

Phase 2 — Secondary content (after users + content exist)

Media — remote images & attachments (opt-in, budgeted)

Migrated posts still load their images from wherever they were hosted (imgur, the old domain, a dead image host). These two steps bring the files onto your own server — into public/assets/files, the folder fof/upload's local adapter uses — and repoint the posts at the local copies.

They are outside every guided sequence (Run everything never triggers them): they hit the network and consume disk, so they are always an explicit decision, taken with a limit, after eyeballing a sample.

Nothing here has to be typed in by hand. With the settings still empty, the panel auto-detects on first open (and the commands do the same when run from the CLI):

Option Meaning
--hosts=a,b Hosts (or full URL prefixes) to localize. A bare host also matches its subdomains. Reads the panel setting when omitted.
--all-hosts Localize every external image, ignoring the filter.
--limit=N Max new URLs attempted this run — downloaded or failed. 0 = no cap.
--max-mb=N Total download budget for the run. 0 = no cap.
--max-file-mb=N Per-file cap; the download aborts mid-stream when exceeded.
--discussion=X Only this discussion — accepts an id, a slug or a full Flarum discussion URL. Implies no per-run cap (the discussion is the scope) and gives the panel an exact progress percentage.
--posts=N, --from-id=N Narrow the scan window.
--dry-run Report only.
--retry-failed Try URLs previously recorded as dead again.
--relink-only No network at all: only re-apply URLs already downloaded.
--uploads-dir=PATH (attachments) Copy from the MyBB uploads folder instead of downloading.
--include-hidden (attachments) Also take attachments still pending approval.
--host-delay=MS Minimum gap between requests to the same host (default 350 ms). Raise it when a host keeps answering 429.
--retries=N Retries for transient failures — 429, 5xx, timeouts (default 3), with exponential backoff that honours Retry-After.
--timeout=S Seconds without traffic before giving up (default 20). A slow-but-progressing download is no longer killed.
--quality=N Re-encoding quality, 30-100 (default 82).
--max-dim=N Resize anything whose longest side exceeds N pixels (default 1600; 0 keeps the original size).
--no-webp Optimize without converting to WebP — keeps the source format.
--no-optimize Store the bytes exactly as downloaded: no re-encoding, no resizing.
--imgur-client-id=ID imgur API Client-ID (overrides the panel). Each imgur image is resolved with one authenticated API call instead of guessing extensions at i.imgur.com.
--imgur-daily-cap=N Maximum imgur API calls per UTC day, persisted across runs (default no local cap; 0 = no cap). Once reached, remaining imgur URLs are deferred to the next day.
--no-defer Retry DNS/connection failures inline instead of pushing those URLs to the end of the run.
--insecure Skip TLS certificate verification. Off by default: a host with a broken chain fails with a clear curl 60 error instead of being silently accepted, because with verification off anyone on the network path could replace the images being imported.
--private-dir=PATH Where private-discussion uploads actually live (overrides the panel setting; only relevant with ramon/dfs installed — see "Restricted tags" below). storage/dfs-private-uploads keeps pointing here via a symlink/junction.
--locale=xx Language of this run's output (e.g. pt-BR). Defaults to the panel setting, then to the forum's default_locale.

Scan order: newest discussions first (by discussion id, newest posts first inside each), so a run with a budget localizes what readers open today before it reaches the threads from 2010.

What makes re-running safe:

Hosts that do not answer (dead DNS, refused connections) do not stall the scan:

imgur with an API Client-ID (Images tab, or --imgur-client-id):

Dead-image handling worth knowing about:

Rate limits and slow hosts

An old forum concentrates hundreds of images on a handful of hosts, so downloading them as fast as possible is the reliable way to earn HTTP 429 in bulk. The fetcher therefore:

Optimization on import (WebP)

Forum images from 2010 are camera JPEGs: 3000 px and 2 MB to be shown at 700 px. Every downloaded image is re-encoded before it is written, which typically removes 80-90 % of the disk it would otherwise take. This is the only cheap moment to do it — afterwards, changing the image format means rewriting the XML of thousands of posts.

The file name carries the real format (mybb-<hash>.webp), and attachments keep their original name with the new extension (holiday.jpg → holiday.webp), so a download never lies about what is inside. Non-image attachments (zip, pdf) are copied byte for byte.

Console language

The output of these steps is what the admin panel's console shows, so it is translated like the rest of the extension — locale/en.yml and locale/pt-BR.yml, under ramon-mybb-migrator.cli. The language is picked, in order, from --locale=xx, the Console output language field on the Connection tab (mybb-migrator.cli_locale), and the forum's default_locale.

If a run ever prints raw keys (ramon-mybb-migrator.cli.…) instead of text, the compiled catalogue under storage/locale is stale — delete that directory's contents (cache:clear does not touch it) and the next run rebuilds it.

Optimizing what is already localized

mybb:optimize-media walks the files already in mybb_migrated_images and re-encodes them with the same rules — for forums migrated before optimization existed, or downloaded with --no-optimize. Per file, in this order, so a post never points at a file that is gone:

  1. the new file is written (the old one is still there);
  2. the fof_upload_files row is repointed, base name included;
  3. the posts are rewritten — a literal replace of the file name inside the XML, which covers the <IMG src> and the [img] token in one pass;
  4. the map row is updated;
  5. only then is the old file deleted (--keep-old skips this).

Files stored outside the document root (restricted tags) are re-encoded on their own side and stay there. --dry-run reports the whole balance without writing anything; --kind=image|attachment and --limit=N narrow the run.

Three sweeps, each repointing a different place — the map (fof_upload_files + posts), files on disk with no map row, and avatars (users.avatar_url), which are usually the biggest pile of leftover JPEGs in a migrated forum. Avatar @2x/@3x variants change format together with their base file or not at all, because the core derives their path from it.

Option Meaning
--all Every image in the forum: map + orphan files + avatars. This is what the panel's "optimize ALL images" step runs.
--include-orphans, --include-avatars, --skip-map Pick the sweeps one by one.
--dry-run Report only — nothing written, repointed or deleted.
--limit=N Max files this run. 0 = all.
--kind=X image, attachment or all (default).
--keep-old Leave the pre-optimization file on disk after repointing.
--quality, --max-dim, --min-gain, --no-webp Same meaning as on mybb:images. --min-gain=0 keeps the WebP whenever it is not bigger.

Restricted tags: files are written outside the document root, not moved later

public/assets/files is served by the web server without PHP ever running, so while a file sits there no permission of any kind applies to it. For a forum imported with restricted tags that matters: the images of a private area would be readable by anyone holding the URL.

ramon/dfs solves this by keeping tag-scoped uploads in storage/dfs-private-uploads and serving them through a permission-checked route. This extension does not reimplement any of that — it just makes sure the bytes never land on the wrong side to begin with:

Without ramon/dfs installed all of this switches off and files are written publicly, which is the only possible destination in that case.

Choosing where that private store actually lives (--private-dir=PATH, or the "Private uploads folder" field on the Images tab, only shown when ramon/dfs is detected): storage/dfs-private-uploads is a hardcoded constant in ramon/dfs's own code, not a setting — it has to be exactly there for the gated route to find the files. So instead of writing somewhere else, this extension turns that path into a symlink pointing at the folder you chose — handy when the forum's storage disk is small, or you'd rather keep these files on a separate volume or backup schedule. ramon/dfs keeps reading from storage/dfs-private-uploads exactly as before and never notices the difference. On Windows, creating a directory symlink needs Developer Mode or an elevated process; when that's not available, nothing is shelled out to work around it — the run tells you the exact mklink /J command to run by hand in an elevated prompt instead. Nothing here is destructive: a folder that already exists at the canonical path with files in it is left untouched and the run just says why linking was skipped, rather than moving production data around on its own.

The URL frozen into the post is /assets/files/… either way — that is precisely what GatePrivateUploads looks for when it rewrites a render to the gated route. Only the location of the bytes differs.

fof/upload is optional: without it the files are still downloaded and the posts do point at the local copies — they just won't appear in the media manager. With it installed, each file is also registered in fof_upload_files and linked to its post. The insert is schema-introspective, so it works across fof/upload versions (which have moved columns around several times).

Attachments are appended to the end of the post — the [attachment=N] tokens were dropped during content migration, and MyBB itself renders non-inlined attachments at the bottom. The post is rewritten through unparse → text → parse, the same path Flarum uses when a post is edited, so the resulting XML is always valid.

All of this is also driven from the Images & attachments tab of the extension's admin page. The tab opens with the URLs to localize and the uploads folder already filled in by auto-detection, and adds a "Localize this discussion" box: paste a discussion URL and only its images are fetched. Both steps run detached in the background, reporting a live progress bar — a real percentage when the total is cheap to know (a single discussion, the attachment table), and an indeterminate bar with the running count otherwise. Counting 273k posts up front just to draw a percentage would cost more than the work itself, so the bar says "unknown" instead of inventing one.

Phase 3 — Content clean-up / fidelity passes (run as needed)

These are idempotent fix-up passes over already-migrated content. They were created to repair specific artifacts found in this forum's data (Tapatalk emoji, mojibake, literal BBCode that didn't parse, quote/mention styling, signatures). Run only the ones you need; safe to re-run.

Do not run them all blindly. They are specific to your dataset and some are opposites of each other (e.g. restore-quote-mentions ↔ revert-quote-mentions, fix-quotes ↔ compact-quotes) — running everything would undo itself. Migrate Phases 1–2 first, look at the live forum, then apply only the passes you actually need. The most commonly needed ones are fix-charset, fix-smilies, fix-emojis, normalize-bbcode, fix-user-mentions and fix-signatures.

About mybb:rebuild-formatting. Because it re-reads each affected post from the MyBB source and re-parses it, it overwrites posts.content and therefore drops any earlier Phase-3 edits on those posts (smilies, mentions, quote styling, strike/spoiler reverts). After running it, re-run the idempotent Phase-3 passes you use — typically fix-smilies, fix-quotes (or your chosen quote-style pass), fix-user-mentions, fix-mention-slugs, and any revert-md-strike-sub / revert-ispoiler — to restore them. The converter itself is now fixed, so a fresh mybb:content migration no longer produces these markdown artifacts in the first place.

Helpers / diagnostics


5. How passwords keep working

MyBB stores either the classic hash md5(md5(salt) . md5(password)) or, with the DVZ Hash plugin, a bcrypt hash ($2y$..., sometimes bcrypt over the classic md5).

  1. mybb:users copies each original hash/salt/algorithm into the companion table mybb_legacy_passwords (created by this extension's migration).
  2. A custom Flarum password checker (mybb-legacy, see src/Auth/MybbPasswordChecker.php) intercepts logins:
    • if a legacy row exists, it verifies the password the MyBB way (src/Support/MybbPassword.php);
    • on success it re-hashes to Flarum bcrypt, saves, and deletes the legacy row — so each user is upgraded transparently on first login.

No password resets, no e-mails — users log in with their existing credentials.


6. Architecture

Design notes:


7. Caveats


8. License

MIT.


All versions of mybb-migrator with dependencies

PHP Build Version
Package Version
Requires php Version ^8.3
flarum/core Version ^2.0
ext-pdo Version *
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package ramon/mybb-migrator contains the following files

Loading the files please wait ...