From b434770e5bef6e9779e7465bb17360450ff1d5f5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Gaya?= <sebastien.gaya@gmail.com>
Date: Mon, 23 Jan 2023 17:49:13 +0100
Subject: [PATCH] handle categories i18n

---
 .../websites/categories_controller.rb         | 21 ++++++++------
 .../websites/posts_controller.rb              |  2 +-
 app/models/communication/website/category.rb  | 11 +++++--
 app/models/communication/website/post.rb      |  2 +-
 .../website/with_program_categories.rb        |  5 ++--
 .../websites/categories/_form.html.erb        |  2 +-
 .../websites/categories/show.html.erb         |  1 +
 .../websites/posts/_form.html.erb             | 29 ++++++++++---------
 ...ication_website_categories_translatable.rb | 12 ++++++++
 db/schema.rb                                  |  8 ++++-
 10 files changed, 63 insertions(+), 30 deletions(-)
 create mode 100644 db/migrate/20230123162224_set_communication_website_categories_translatable.rb

diff --git a/app/controllers/admin/communication/websites/categories_controller.rb b/app/controllers/admin/communication/websites/categories_controller.rb
index 6f0b27b6e..bf7a02611 100644
--- a/app/controllers/admin/communication/websites/categories_controller.rb
+++ b/app/controllers/admin/communication/websites/categories_controller.rb
@@ -1,10 +1,12 @@
 class Admin::Communication::Websites::CategoriesController < Admin::Communication::Websites::ApplicationController
   load_and_authorize_resource class: Communication::Website::Category, through: :website
 
+  include Admin::Translatable
+
   before_action :get_root_categories, only: [:index, :new, :create, :edit, :update]
 
   def index
-    @categories = @website.categories.ordered
+    @categories = @website.categories.where(language_id: current_website_language.id).ordered
     breadcrumb
   end
 
@@ -30,7 +32,7 @@ class Admin::Communication::Websites::CategoriesController < Admin::Communicatio
 
   def children
     return unless request.xhr?
-    @category = @website.categories.find(params[:id])
+    @category = @website.categories.where(language_id: current_website_language.id).find(params[:id])
     @children = @category.children.ordered
   end
 
@@ -84,7 +86,7 @@ class Admin::Communication::Websites::CategoriesController < Admin::Communicatio
   protected
 
   def get_root_categories
-    @root_categories = @website.categories.root.ordered
+    @root_categories = @website.categories.root.where(language_id: current_website_language.id).ordered
   end
 
   def breadcrumb
@@ -95,11 +97,12 @@ class Admin::Communication::Websites::CategoriesController < Admin::Communicatio
   end
 
   def category_params
-    params.require(:communication_website_category)
-          .permit(
-            :website_id, :name, :meta_description, :summary, :slug, :parent_id,
-            :featured_image, :featured_image_delete, :featured_image_infos, :featured_image_alt, :featured_image_credit
-          )
-          .merge(university_id: current_university.id)
+    translatable_params(
+      :communication_website_category,
+      [
+        :name, :meta_description, :summary, :slug, :parent_id,
+        :featured_image, :featured_image_delete, :featured_image_infos, :featured_image_alt, :featured_image_credit
+      ]
+    )
   end
 end
diff --git a/app/controllers/admin/communication/websites/posts_controller.rb b/app/controllers/admin/communication/websites/posts_controller.rb
index a03fc53b6..e271c0504 100644
--- a/app/controllers/admin/communication/websites/posts_controller.rb
+++ b/app/controllers/admin/communication/websites/posts_controller.rb
@@ -17,7 +17,7 @@ class Admin::Communication::Websites::PostsController < Admin::Communication::We
     @authors =  @website.authors.accessible_by(current_ability)
                                 .ordered
                                 .page(params[:authors_page])
-    @root_categories = @website.categories.root.ordered
+    @root_categories = @website.categories.where(language_id: current_website_language.id).root.ordered
     breadcrumb
   end
 
diff --git a/app/models/communication/website/category.rb b/app/models/communication/website/category.rb
index ba31fe564..2658bb7db 100644
--- a/app/models/communication/website/category.rb
+++ b/app/models/communication/website/category.rb
@@ -16,6 +16,8 @@
 #  created_at               :datetime         not null
 #  updated_at               :datetime         not null
 #  communication_website_id :uuid             not null, indexed
+#  language_id              :uuid             not null, indexed
+#  original_id              :uuid             indexed
 #  parent_id                :uuid             indexed
 #  program_id               :uuid             indexed
 #  university_id            :uuid             not null, indexed
@@ -23,12 +25,16 @@
 # Indexes
 #
 #  idx_communication_website_post_cats_on_communication_website_id  (communication_website_id)
+#  index_communication_website_categories_on_language_id            (language_id)
+#  index_communication_website_categories_on_original_id            (original_id)
 #  index_communication_website_categories_on_parent_id              (parent_id)
 #  index_communication_website_categories_on_program_id             (program_id)
 #  index_communication_website_categories_on_university_id          (university_id)
 #
 # Foreign Keys
 #
+#  fk_rails_3186d8e327  (language_id => languages.id)
+#  fk_rails_52bd5968c9  (original_id => communication_website_categories.id)
 #  fk_rails_86a9ce3cea  (parent_id => communication_website_categories.id)
 #  fk_rails_9d4210dc43  (university_id => universities.id)
 #  fk_rails_c7c9f7ddc7  (communication_website_id => communication_websites.id)
@@ -46,6 +52,7 @@ class Communication::Website::Category < ApplicationRecord
   include WithTree
   include WithPermalink
   include WithPosition
+  include WithTranslations
 
   has_one                 :imported_category,
                           class_name: 'Communication::Website::Imported::Category',
@@ -121,11 +128,11 @@ class Communication::Website::Category < ApplicationRecord
   protected
 
   def last_ordered_element
-    website.categories.where(parent_id: parent_id).ordered.last
+    website.categories.where(parent_id: parent_id, language_id: language_id).ordered.last
   end
 
   def slug_unavailable?(slug)
-    self.class.unscoped.where(communication_website_id: self.communication_website_id, slug: slug).where.not(id: self.id).exists?
+    self.class.unscoped.where(communication_website_id: self.communication_website_id, language_id: language_id, slug: slug).where.not(id: self.id).exists?
   end
 
   def explicit_blob_ids
diff --git a/app/models/communication/website/post.rb b/app/models/communication/website/post.rb
index 83fb30bac..3a9302d2a 100644
--- a/app/models/communication/website/post.rb
+++ b/app/models/communication/website/post.rb
@@ -152,7 +152,7 @@ class Communication::Website::Post < ApplicationRecord
 
   def slug_unavailable?(slug)
     self.class.unscoped
-              .where(communication_website_id: self.communication_website_id, slug: slug)
+              .where(communication_website_id: self.communication_website_id, language_id: language_id, slug: slug)
               .where.not(id: self.id)
               .exists?
   end
diff --git a/app/models/communication/website/with_program_categories.rb b/app/models/communication/website/with_program_categories.rb
index 109e50965..1e24ca27c 100644
--- a/app/models/communication/website/with_program_categories.rb
+++ b/app/models/communication/website/with_program_categories.rb
@@ -5,8 +5,9 @@ module Communication::Website::WithProgramCategories
     after_save_commit :set_programs_categories!, if: -> (website) { website.has_education_programs? }
   end
 
+  # TODO : I18n
   def set_programs_categories!
-    programs_root_category = categories.where(is_programs_root: true).first_or_create(
+    programs_root_category = categories.where(language_id: default_language_id, is_programs_root: true).first_or_create(
       name: 'Offre de formation',
       slug: 'offre-de-formation',
       is_programs_root: true,
@@ -20,7 +21,7 @@ module Communication::Website::WithProgramCategories
 
   def set_programs_categories_at_level!(parent_category, programs)
     programs.map.with_index do |program, index|
-      category = categories.where(program_id: program.id).first_or_initialize(
+      category = categories.where(language_id: default_language_id, program_id: program.id).first_or_initialize(
         name: program.name,
         slug: program.name.parameterize,
         university_id: university.id
diff --git a/app/views/admin/communication/websites/categories/_form.html.erb b/app/views/admin/communication/websites/categories/_form.html.erb
index ad011b1a6..043acb3ef 100644
--- a/app/views/admin/communication/websites/categories/_form.html.erb
+++ b/app/views/admin/communication/websites/categories/_form.html.erb
@@ -28,7 +28,7 @@
                         data: { source: '#communication_website_category_name' }
                       } %>
           <%= f.association :parent,
-                            collection: collection_tree(@website.categories, category),
+                            collection: collection_tree(@website.categories.where(language_id: current_website_language.id), category),
                             label_method: ->(p) { sanitize p[:label] },
                             value_method: ->(p) { p[:id] } %>
           <ul>
diff --git a/app/views/admin/communication/websites/categories/show.html.erb b/app/views/admin/communication/websites/categories/show.html.erb
index 64944461b..cde4327de 100644
--- a/app/views/admin/communication/websites/categories/show.html.erb
+++ b/app/views/admin/communication/websites/categories/show.html.erb
@@ -7,6 +7,7 @@
       <%= render 'admin/communication/blocks/list', about: @category %>
     </div>
     <div class="col-md-4">
+      <%= render 'admin/application/i18n/widget', about: @category %>
       <div class="card flex-fill w-100">
         <div class="card-header">
           <h2 class="card-title mb-0 h5"><%= t('metadata') %></h2>
diff --git a/app/views/admin/communication/websites/posts/_form.html.erb b/app/views/admin/communication/websites/posts/_form.html.erb
index 6e5599e6c..e1f148e84 100644
--- a/app/views/admin/communication/websites/posts/_form.html.erb
+++ b/app/views/admin/communication/websites/posts/_form.html.erb
@@ -15,21 +15,24 @@
         </div>
       </div>
       <div class="row">
-        <div class="col-md-6">
-          <div class="card flex-fill w-100">
-            <div class="card-header">
-              <h5 class="card-title mb-0">
-                <%= t('activerecord.attributes.communication/website/post.categories') %>
-              </h5>
-            </div>
-            <div class="card-body">
-              <%= f.association :categories,
-                                label_text: false,
-                                as: :check_boxes,
-                                collection: collection_tree_for_checkboxes(@website.categories) if @website.categories.any? %>
+        <% categories = @website.categories.where(language_id: current_website_language.id) %>
+        <% if categories.any? %>
+          <div class="col-md-6">
+            <div class="card flex-fill w-100">
+              <div class="card-header">
+                <h5 class="card-title mb-0">
+                  <%= t('activerecord.attributes.communication/website/post.categories') %>
+                </h5>
+              </div>
+              <div class="card-body">
+                  <%= f.association :categories,
+                                    label_text: false,
+                                    as: :check_boxes,
+                                    collection: collection_tree_for_checkboxes(categories) %>
+              </div>
             </div>
           </div>
-        </div>
+        <% end %>
         <div class="col-md-6">
           <%= render 'admin/application/meta_description/form', f: f, about: post %>
         </div>
diff --git a/db/migrate/20230123162224_set_communication_website_categories_translatable.rb b/db/migrate/20230123162224_set_communication_website_categories_translatable.rb
new file mode 100644
index 000000000..6d4b7bc7f
--- /dev/null
+++ b/db/migrate/20230123162224_set_communication_website_categories_translatable.rb
@@ -0,0 +1,12 @@
+class SetCommunicationWebsiteCategoriesTranslatable < ActiveRecord::Migration[7.0]
+  def change
+    add_reference :communication_website_categories, :original, foreign_key: {to_table: :communication_website_categories}, type: :uuid
+    add_reference :communication_website_categories, :language, foreign_key: true, type: :uuid
+
+    Communication::Website.find_each do |website|
+      website.categories.where(language_id: nil).update_all(language_id: website.default_language_id)
+    end
+
+    change_column_null :communication_website_categories, :language_id, false
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index dadd362de..12f9e407f 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
 #
 # It's strongly recommended that you check this file into your version control system.
 
-ActiveRecord::Schema[7.0].define(version: 2023_01_23_150502) do
+ActiveRecord::Schema[7.0].define(version: 2023_01_23_162224) do
   # These are extensions that must be enabled in order to support this database
   enable_extension "pgcrypto"
   enable_extension "plpgsql"
@@ -134,7 +134,11 @@ ActiveRecord::Schema[7.0].define(version: 2023_01_23_150502) do
     t.string "featured_image_alt"
     t.text "summary"
     t.text "featured_image_credit"
+    t.uuid "original_id"
+    t.uuid "language_id", null: false
     t.index ["communication_website_id"], name: "idx_communication_website_post_cats_on_communication_website_id"
+    t.index ["language_id"], name: "index_communication_website_categories_on_language_id"
+    t.index ["original_id"], name: "index_communication_website_categories_on_original_id"
     t.index ["parent_id"], name: "index_communication_website_categories_on_parent_id"
     t.index ["program_id"], name: "index_communication_website_categories_on_program_id"
     t.index ["university_id"], name: "index_communication_website_categories_on_university_id"
@@ -884,9 +888,11 @@ ActiveRecord::Schema[7.0].define(version: 2023_01_23_150502) do
   add_foreign_key "administration_qualiopi_indicators", "administration_qualiopi_criterions", column: "criterion_id"
   add_foreign_key "communication_blocks", "universities"
   add_foreign_key "communication_extranets", "universities"
+  add_foreign_key "communication_website_categories", "communication_website_categories", column: "original_id"
   add_foreign_key "communication_website_categories", "communication_website_categories", column: "parent_id"
   add_foreign_key "communication_website_categories", "communication_websites"
   add_foreign_key "communication_website_categories", "education_programs", column: "program_id"
+  add_foreign_key "communication_website_categories", "languages"
   add_foreign_key "communication_website_categories", "universities"
   add_foreign_key "communication_website_git_files", "communication_websites", column: "website_id"
   add_foreign_key "communication_website_imported_authors", "communication_website_imported_websites", column: "website_id"
-- 
GitLab