Skip to content

Refactor Message model to centralize column definitions - #114

Merged
mjauvin merged 5 commits into
wintercms:mainfrom
matteotrubini:refactor/import-export
Mar 19, 2026
Merged

Refactor Message model to centralize column definitions#114
mjauvin merged 5 commits into
wintercms:mainfrom
matteotrubini:refactor/import-export

Conversation

@matteotrubini

@matteotrubini matteotrubini commented Mar 19, 2026

Copy link
Copy Markdown
Contributor
  • Move CODE_COLUMN_NAME and DEFAULT_COLUMN_NAME constants from MessageExport to Message model, leaving deprecated alias for backward compatibility
  • Add shared getColumns() method to Message for reuse
  • Update MessageImport to use the shared columns
  • Update MessageExport to use the shared columns, plus "found"

The last point is particularly important to avoid losing the "found" data in the export for human review, but it is unnecessary in the import since the system recalculates it.

Summary by CodeRabbit

  • New Features

    • Centralized message import/export column configuration.
    • Added a "found" column to message exports.
  • Bug Fixes

    • More consistent export output with safer fallbacks when values are missing.
  • Chores

    • Marked legacy export column identifiers as deprecated.

- Move CODE_COLUMN_NAME and DEFAULT_COLUMN_NAME constants from MessageExport to Message model, leaving deprecated alias for backward compatibility
- Add shared getColumns() method to Message for reuse
- Update MessageImport to use the shared columns
- Update MessageExport to use the shared columns, plus "found"
@coderabbitai

coderabbitai Bot commented Mar 19, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 91478728-4721-4281-acd2-02c09f66d299

📥 Commits

Reviewing files that changed from the base of the PR and between 161283d and 4c14a46.

📒 Files selected for processing (3)
  • models/MessageExport.php
  • models/MessageImport.php
  • tests/unit/models/ExportMessageTest.php
🚧 Files skipped from review as they are similar to previous changes (1)
  • models/MessageImport.php

Walkthrough

Adds column-name constants and a shared getColumns() to Message; updates MessageExport/MessageImport to delegate column definitions to Message and adjust export/import handling; updates controller to source import columns from MessageImport::getColumns(); tests updated accordingly.

Changes

Cohort / File(s) Summary
Message model
models/Message.php
Add CODE_COLUMN_NAME and DEFAULT_COLUMN_NAME constants and public static function getColumns(): array returning base import/export columns (code, default, plus locale columns).
Export logic
models/MessageExport.php
Make CODE_COLUMN_NAME/DEFAULT_COLUMN_NAME deprecated aliases of Message constants; change getColumns() to return Message::getColumns() plus a 'found' => 'found' entry; modify exportData to treat message_data as optional and prefer message_data[$column] with fallback to ($message->$column ?? '').
Import logic
models/MessageImport.php
Add public static function getColumns(): array delegating to Message::getColumns(); update importData to reference Message::CODE_COLUMN_NAME (method signature remains unchanged).
Controller wiring
controllers/Messages.php
Add use Winter\Translate\Models\MessageImport and set $this->importColumns from MessageImport::getColumns() instead of MessageExport::getColumns().
Tests
tests/unit/models/ExportMessageTest.php
Update expected keys/values in testGetColumns() to reference Message constants and include additional 'found' => 'found' entry.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title 'Refactor Message model to centralize column definitions' accurately and clearly summarizes the main change: moving column constants from MessageExport to the Message model and creating a shared getColumns() method.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@models/MessageExport.php`:
- Around line 32-39: The export breaks when message_data is null because
array_key_exists() is invoked on a nullable value; normalize
$message->message_data at the start of the closure (e.g., $data =
$message->message_data ?: []) before using array_key_exists so the rest of the
loop (in the Message::all()->map(...) closure where $data and $columns are used)
safely treats absent JSON as an empty array.
- Line 30: The override of exportData in MessageExport.php uses strict parameter
and return type hints that conflict with Backend\Models\ExportModel::exportData;
remove the type declarations so the signature matches the untyped parent (change
"public function exportData(array $columns, ?string $sessionKey = null): array"
to an untyped "public function exportData($columns, $sessionKey = null)" while
preserving the parameter names and current implementation and return behavior),
ensuring the method no longer declares parameter or return types but still
returns the same data structure at runtime.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c4233788-b201-4086-b005-db3046131881

📥 Commits

Reviewing files that changed from the base of the PR and between 0988be2 and 84de4f9.

📒 Files selected for processing (4)
  • controllers/Messages.php
  • models/Message.php
  • models/MessageExport.php
  • models/MessageImport.php

Comment thread models/MessageExport.php Outdated
Comment thread models/MessageExport.php
@mjauvin

mjauvin commented Mar 19, 2026

Copy link
Copy Markdown
Member

Hello Matteo, thank you for the PR.

Please address CodeRabbit's flagged issues with the Import/Export model method signature.

Also, please explain the use of the "found" column in the export.

Thanks.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
models/MessageExport.php (1)

30-30: ⚠️ Potential issue | 🔴 Critical

Restore parent-compatible exportData() signature to avoid fatal class loading error.

Line 30 is currently incompatible with Backend\Models\ExportModel::exportData($columns, $sessionKey = null), which causes the reported fatal declaration error.

Compatibility fix
-public function exportData(array $columns, ?string $sessionKey = null): array
+public function exportData($columns, $sessionKey = null)
#!/bin/bash
# Verify parent and child method signatures are compatible.
# Expected: both declarations should be untyped in parameters/return for override compatibility in this codebase.

fd -t f "ExportModel.php" --exec sh -c '
  echo "== {} ==";
  rg -n "function exportData\\s*\\(" "{}" -C2;
' \;

echo "== models/MessageExport.php =="
rg -n "function exportData\\s*\\(" models/MessageExport.php -C2
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@models/MessageExport.php` at line 30, The child method
MessageExport::exportData currently declares typed parameters/return (array,
?string) that conflict with Backend\Models\ExportModel::exportData; update
MessageExport::exportData to match the parent signature by removing parameter
and return type declarations so the method signature is untyped (same parameters
$columns, $sessionKey = null) and thus compatible with the parent override.
🧹 Nitpick comments (1)
models/MessageExport.php (1)

46-50: Clarify in docblock that found is export-only metadata.

Given reviewer feedback, consider extending the comment to explicitly state that found is exported for human review and intentionally excluded from import because it is recalculated.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@models/MessageExport.php` around lines 46 - 50, Update the getColumns()
docblock in the MessageExport class to state that the returned columns are the
importable columns plus an export-only metadata flag named 'found' that is
included for human review and intentionally excluded from import because it is
recalculated; reference the method getColumns() and the Message::getColumns()
call and explicitly mention the 'found' flag as export-only metadata in the
comment so future readers know it is not persisted on import.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@models/MessageExport.php`:
- Line 30: The child method MessageExport::exportData currently declares typed
parameters/return (array, ?string) that conflict with
Backend\Models\ExportModel::exportData; update MessageExport::exportData to
match the parent signature by removing parameter and return type declarations so
the method signature is untyped (same parameters $columns, $sessionKey = null)
and thus compatible with the parent override.

---

Nitpick comments:
In `@models/MessageExport.php`:
- Around line 46-50: Update the getColumns() docblock in the MessageExport class
to state that the returned columns are the importable columns plus an
export-only metadata flag named 'found' that is included for human review and
intentionally excluded from import because it is recalculated; reference the
method getColumns() and the Message::getColumns() call and explicitly mention
the 'found' flag as export-only metadata in the comment so future readers know
it is not persisted on import.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 74e92aa0-f1b0-4982-a056-5170d38e06cf

📥 Commits

Reviewing files that changed from the base of the PR and between 84de4f9 and 0e00829.

📒 Files selected for processing (1)
  • models/MessageExport.php

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
models/MessageExport.php (1)

9-19: Use /** for DocBlock comments to enable deprecation warnings.

The deprecation annotations use /* (regular comment) instead of /** (DocBlock). IDEs and documentation tools won't recognize the @deprecated tags, so developers won't receive proper deprecation warnings when using these constants.

Fix DocBlock syntax
-    /*
+    /**
      * `@deprecated` since version 2.3.2, use \Winter\Translate\Models\Message::CODE_COLUMN_NAME directly
      * `@see` \Winter\Translate\Models\Message::CODE_COLUMN_NAME
      */
     const CODE_COLUMN_NAME = \Winter\Translate\Models\Message::CODE_COLUMN_NAME;

-    /*
+    /**
      * `@deprecated` since version 2.3.2, use \Winter\Translate\Models\Message::DEFAULT_COLUMN_NAME directly
      * `@see` \Winter\Translate\Models\Message::DEFAULT_COLUMN_NAME
      */
     const DEFAULT_COLUMN_NAME = \Winter\Translate\Models\Message::DEFAULT_COLUMN_NAME;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@models/MessageExport.php` around lines 9 - 19, The deprecation comments for
the constants are regular comments, so change both comment blocks to proper
DocBlock syntax (use /** ... */) above the constants CODE_COLUMN_NAME and
DEFAULT_COLUMN_NAME in MessageExport so tooling/IDEs pick up the `@deprecated` and
`@see` annotations; preserve the existing `@deprecated` text and the `@see` reference
to \Winter\Translate\Models\Message::CODE_COLUMN_NAME and ::DEFAULT_COLUMN_NAME.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@models/MessageExport.php`:
- Around line 9-19: The deprecation comments for the constants are regular
comments, so change both comment blocks to proper DocBlock syntax (use /** ...
*/) above the constants CODE_COLUMN_NAME and DEFAULT_COLUMN_NAME in
MessageExport so tooling/IDEs pick up the `@deprecated` and `@see` annotations;
preserve the existing `@deprecated` text and the `@see` reference to
\Winter\Translate\Models\Message::CODE_COLUMN_NAME and ::DEFAULT_COLUMN_NAME.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8a2701f4-2ecf-492a-aaf4-e84e292ebdd2

📥 Commits

Reviewing files that changed from the base of the PR and between 0e00829 and 161283d.

📒 Files selected for processing (1)
  • models/MessageExport.php

@matteotrubini
matteotrubini force-pushed the refactor/import-export branch from 161283d to 8dfa28b Compare March 19, 2026 14:14
@matteotrubini

Copy link
Copy Markdown
Contributor Author

I apologize for the inaccuracies—this PR comes from work done live for a client.
For easier review, I’ve kept the commits separate. Would you like me to squash them before merging?

@mjauvin

mjauvin commented Mar 19, 2026

Copy link
Copy Markdown
Member

I apologize for the inaccuracies—this PR comes from work done live for a client. For easier review, I’ve kept the commits separate. Would you like me to squash them before merging?

No, that's fine.

What's the need for the found column in the export model ?

@mjauvin
mjauvin merged commit c90e8d6 into wintercms:main Mar 19, 2026
4 checks passed
@matteotrubini

Copy link
Copy Markdown
Contributor Author

The absence of the "found" column in the export results in the loss of a critical data point for human review. Over time, unused translations may accumulate; while they should not necessarily be removed, as they can still represent a valuable resource, the lack of the "found" field in the export makes it impossible to accurately scope and prioritize the content relevant at a given point in time.

@matteotrubini
matteotrubini deleted the refactor/import-export branch March 19, 2026 17:43
@matteotrubini
matteotrubini restored the refactor/import-export branch March 28, 2026 16:12
@matteotrubini
matteotrubini deleted the refactor/import-export branch March 28, 2026 16:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants