The process_user_email method was replacing valid emails with random
@email.invalid addresses because the deduplication check treated a
user's own email as a duplicate.
The @emails hash is populated during import_users, so when
import_user_emails runs later, the check !@emails.has_key?(email) fails
for the user's own email, triggering the random_email fallback.
Updated the condition to allow an email if it belongs to the same user:
(!@emails.has_key?(email) || @emails[email] == user_id)
- Add BOOKMARK_COLUMNS, create_bookmarks, and process_bookmark to
base.rb
- Implement import_bookmarks in generic_bulk.rb for Topic and Post
bookmarks
- Track bookmark sequence IDs to prevent conflicts
- Update topic_users.bookmarked flag after bookmark import
- Add refresh_directory_items to sync user stats post-import
Category changes:
- Fix existing_id handling to check if string is numeric before using as
site setting name. Previously numeric strings like '3' would cause
errors when passed to SiteSetting.get().
Group changes:
- Add existing_id support for groups, allowing mapping imported groups
to existing Discourse groups by ID or name.
- When existing_id is specified, skip group creation and map imported_id
to the existing group.
This enables importing users into pre-existing groups without creating
duplicates, similar to category existing_id functionality.
Co-authored-by: root <root@migrations02.sjc4.discourse.cloud>
Fixes operator precedence issue where `name.presence || username` was
being evaluated after the array append, resulting in nil being added
to bbcode_parts when name is nil.
The fix wraps the expression in parentheses to ensure the || operator
We can't enable `Rails/WhereNot` lint/autofix, because it would break
code that uses mini_sql instead of AR (which rubocop, and tbh also we,
can't easily differentiate)
Those are safe because they either:
* are executed in AR model scope definitions
* are clearly chained starting from a AR model
* are less-clearly chained, but still can be traced to a AR model/scope
---------
Co-authored-by: Loïc Guitaut <loic@discourse.org>
In #33558 we removed automatic_backups_enabled setting, and instead rely on backup_frequency being blank to disable.
There was a big oversight there with the site setting type system, which will coerce the value to an integer. It also makes it so you can't blank the value out in the UI.
This is a "fix forward" solution where instead of "set to blank to disable" we do "set to 0 to disable". This works along the grain of the site setting type system for a workable fix where we don't have to deal with the irreversible migration in the previous change.
We can potentially go and add in "nullable" to the type system at a later point.
We're removing the automatic_backups_enabled toggle and depending solely on the backup_frequency value. This PR replaces the setting and adds a migration for any forum that has automatic_backups_enabled disabled.
This commit responds to feedback in the Discourse Meta discussion
https://meta.discourse.org/t/monospace-font-in-the-markdown-only-editor/359936
This change introduces a user preference that allows users to choose
whether the Markdown editor uses a monospace font. The default setting
is `true` for new sites, but set to `false` for existing sites to avoid
disrupting current users' experiences.
Admins can change the `default_other_enable_markdown_monospace_font`
site setting to manage this for all users.
We believe the rich editor is a great experience for the
vast majority of sites and users, so we are enabling it
for all sites and all users by default.
This commit does the following:
* Hides the rich_editor site setting and sets it to true by default.
It can still be overridden by sites that want to disable it
completely.
* Sets `rich_editor` to true for all sites to enable the rich editor
everywhere.
* Adds a new `default_composition_mode` site setting and corresponding
user option that defaults to Rich for all users. The other option is
Markdown.
* Changes the rich editor toggle in the composer to use the new
database-backed user option (`composition_mode`) instead of a local
storage key/value store. This makes the preference persistent
across devices.
Existing key/value store settings for the markdown toggle are
kept, the preference will be saved to the user option automatically.
This change makes it easier to review failed uploads, especially
downloadable ones, by standardizing `skip_reason` and adding a
`skip_details` column to the uploads DB's `uploads` table for extended
failure information.
1. Ensure `Creating optimized images...` message is only available
during optimization
2. Guard upload lookup for optimization
3. Replace undefined `stacktrace` method invocation with `backtrace`
This PR improves the generic bulk import and base scripts by adding
support for several previously unimplemented features and attributes:
- Category Moderation Groups: Implements the import of group-based
moderation settings for categories.
- Group Attributes: Adds import support for public_admission,
public_exit, allow_membership_requests, and assignable_level.
- User Attributes: Adds import support for trust_level and
primary_group_id.
- User Option: Adds import support for the hide_profile_and_presence
user option.
- Multiple Tag Groups per Tag: Updates tag import logic to handle tags
belonging to multiple tag groups.
Extend the `import_site_settings` import step to enable the
`migrated_site` flag if possible.
It also includes an escape hatch via the
`SKIP_MIGRATED_SITE_FLAG_UPDATE` flag for cases where you really don't
want to toggle it on.
Ensure `last_read_post_number` is set to the latest post for imported
topic users with a `watching` notification level, even if they haven't
engaged with the topic
Empty slugs for topics break Discourse. This makes sure that we always
fall back to "topic" as default. And it also uses the configured slug
generation method instead of always using ASCII.
It splits the hide_profile_and_presence user option and the default_hide_profile_and_presence site setting for more granular control. It keeps the option to hide the profile under /u/username/preferences/interface and adds the presence toggle in the quick user menu.
Co-authored-by: Régis Hanol <regis@hanol.fr>
DEV: Add import support for Topic Voting plugin
- Implemented bulk import functionality specifically for topic_voting_votes.
- Updated the method name from import_votes to import_post_voting_votes for improved clarity and maintainability.
- Co-authored-by: Gerhard Schlager <gerhard.schlager@discourse.org>
Followup 30fdd7738e
Adds a new site setting and corresponding user preference
to disable smart lists. By default they are enabled, because
this is a better experience for most users. A small number of
users would prefer to not have this enabled.
Smart lists automatically append new items to each
list started in the composer when enter is pressed. If
enter is pressed on an empty list item, it is cleared.
This setting will be removed when the new composer is complete.
Constants should always be only assigned once. The logical OR assignment
of a constant is a relic of the past before we used zeitwerk for
autoloading and had bugs where a file could be loaded twice resulting in
constant redefinition warnings.
The current implementation adds a "note" for chat messages with empty
messages, however chat messages with only uploads are allowed. This change
allows such messages to be imported.
* DEV: WIP generic bulk chat import support
This first iteration implements bulk import for:
* direct_messages
* chat_channels
* user_chat_channel_memberships
* chat_threads
* user_chat_thread_memberships
* chat_messages
* chat_reactions
* chat_mentions
* DEV: Refactor raw placeholder interpolation to support chat messages
This change adds support for chat message placeholder interpolation
and switches to using `Chat::Message.cook` for cooking in the interim
instead of hand-cooking chat messages like we currently do for posts
* DEV: Extend upload references import to support chat message uploads
* DEV: Explicity set chat retention
- Set both channel and dm chats to 0
- Add temporary workaround for testing only chat imports
* DEV: Compute channel and thread membership metadata
Compute and set various user channel/thread membership stats and
remove hardcoded test index seed data
* FIX: Fix chat reactions import
Allow multiple reactions on a message by a user
Currently, quotes imported via generic bulk import script do not include
references to the quoted post. This change includes both topic and post attributes
in a quote if the placeholder metadata includes a `post_id`
* user_profiles - `location`
* users - `date_of_birth`
* topics - `pinned_at`, `pinned_until`, `pinned_globally`
This also include changes to correctly import PMs. Currently PM topics
are skipped because of a check in `import_users` step which requires `category_id`
to be present.