FIX: Associate category logo and background to uploads record.
This commit is contained in:
parent
beb8245d04
commit
9a800107cb
|
@ -1,2 +1,40 @@
|
||||||
import { buildCategoryPanel } from 'discourse/components/edit-category-panel';
|
import { buildCategoryPanel } from 'discourse/components/edit-category-panel';
|
||||||
export default buildCategoryPanel('images');
|
import { default as computed, observes } from 'ember-addons/ember-computed-decorators';
|
||||||
|
|
||||||
|
export default buildCategoryPanel('images').extend({
|
||||||
|
@computed('category.uploaded_background.url')
|
||||||
|
backgroundImageUrl(uploadedBackgroundUrl) {
|
||||||
|
return uploadedBackgroundUrl || '';
|
||||||
|
},
|
||||||
|
|
||||||
|
@computed('category.uploaded_background.id')
|
||||||
|
backgroundImageId(uploadedBackgroundId) {
|
||||||
|
return uploadedBackgroundId || null;
|
||||||
|
},
|
||||||
|
|
||||||
|
@computed('category.uploaded_logo.url')
|
||||||
|
logoImageUrl(uploadedLogoUrl) {
|
||||||
|
return uploadedLogoUrl || '';
|
||||||
|
},
|
||||||
|
|
||||||
|
@computed('category.uploaded_logo.id')
|
||||||
|
logoImageId(uploadedLogoId) {
|
||||||
|
return uploadedLogoId || null;
|
||||||
|
},
|
||||||
|
|
||||||
|
@observes("backgroundImageUrl", "backgroundImageId")
|
||||||
|
_setBackgroundUpload() {
|
||||||
|
this.set("category.uploaded_background", Ember.Object.create({
|
||||||
|
id: this.get('backgroundImageId'),
|
||||||
|
url: this.get('backgroundImageUrl')
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
@observes("logoImageUrl", "logoImageId")
|
||||||
|
_setLogoUpload() {
|
||||||
|
this.set("category.uploaded_logo", Ember.Object.create({
|
||||||
|
id: this.get('logoImageId'),
|
||||||
|
url: this.get('logoImageUrl')
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
|
@ -12,11 +12,13 @@ export default Em.Component.extend(UploadMixin, {
|
||||||
|
|
||||||
uploadDone(upload) {
|
uploadDone(upload) {
|
||||||
this.set("imageUrl", upload.url);
|
this.set("imageUrl", upload.url);
|
||||||
|
this.set("imageId", upload.id);
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
trash() {
|
trash() {
|
||||||
this.set("imageUrl", null);
|
this.set("imageUrl", null);
|
||||||
|
this.set("imageId", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -91,8 +91,8 @@ const Category = RestModel.extend({
|
||||||
email_in: this.get('email_in'),
|
email_in: this.get('email_in'),
|
||||||
email_in_allow_strangers: this.get('email_in_allow_strangers'),
|
email_in_allow_strangers: this.get('email_in_allow_strangers'),
|
||||||
parent_category_id: this.get('parent_category_id'),
|
parent_category_id: this.get('parent_category_id'),
|
||||||
logo_url: this.get('logo_url'),
|
uploaded_logo_id: this.get('uploaded_logo.id'),
|
||||||
background_url: this.get('background_url'),
|
uploaded_background_id: this.get('uploaded_background.id'),
|
||||||
allow_badges: this.get('allow_badges'),
|
allow_badges: this.get('allow_badges'),
|
||||||
custom_fields: this.get('custom_fields'),
|
custom_fields: this.get('custom_fields'),
|
||||||
topic_template: this.get('topic_template'),
|
topic_template: this.get('topic_template'),
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{{#each categories as |c|}}
|
{{#each categories as |c|}}
|
||||||
<tr data-category-id={{c.id}} class="{{if c.description_excerpt 'has-description' 'no-description'}} {{if c.logo_url 'has-logo' 'no-logo'}}">
|
<tr data-category-id={{c.id}} class="{{if c.description_excerpt 'has-description' 'no-description'}} {{if c.uploaded_logo.url 'has-logo' 'no-logo'}}">
|
||||||
<td class="category" style={{border-color c.color}}>
|
<td class="category" style={{border-color c.color}}>
|
||||||
<div>
|
<div>
|
||||||
{{category-title-link category=c}}
|
{{category-title-link category=c}}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
<span class="category-name">{{category.name}}</span>
|
<span class="category-name">{{category.name}}</span>
|
||||||
|
|
||||||
{{#if category.logo_url}}
|
{{#if category.uploaded_logo.url}}
|
||||||
<div>{{cdn-img src=category.logo_url class="category-logo"}}</div>
|
<div>{{cdn-img src=category.uploaded_logo.url class="category-logo"}}</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -1,9 +1,16 @@
|
||||||
<section class='field'>
|
<section class='field'>
|
||||||
<label>{{i18n 'category.logo'}}</label>
|
<label>{{i18n 'category.logo'}}</label>
|
||||||
{{image-uploader imageUrl=category.logo_url type="category_logo" class="no-repeat"}}
|
{{image-uploader
|
||||||
|
imageId=logoImageId
|
||||||
|
imageUrl=logoImageUrl
|
||||||
|
type="category_logo"
|
||||||
|
class="no-repeat"}}
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class='field'>
|
<section class='field'>
|
||||||
<label>{{i18n 'category.background_image'}}</label>
|
<label>{{i18n 'category.background_image'}}</label>
|
||||||
{{image-uploader imageUrl=category.background_url type="category_background"}}
|
{{image-uploader
|
||||||
|
imageId=backgroundImageId
|
||||||
|
imageUrl=backgroundImageUrl
|
||||||
|
type="category_background"}}
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -233,8 +233,8 @@ class CategoriesController < ApplicationController
|
||||||
:parent_category_id,
|
:parent_category_id,
|
||||||
:auto_close_hours,
|
:auto_close_hours,
|
||||||
:auto_close_based_on_last_post,
|
:auto_close_based_on_last_post,
|
||||||
:logo_url,
|
:uploaded_logo_id,
|
||||||
:background_url,
|
:uploaded_background_id,
|
||||||
:slug,
|
:slug,
|
||||||
:allow_badges,
|
:allow_badges,
|
||||||
:topic_template,
|
:topic_template,
|
||||||
|
|
|
@ -21,12 +21,12 @@ module Jobs
|
||||||
.joins("LEFT JOIN users u ON u.uploaded_avatar_id = uploads.id")
|
.joins("LEFT JOIN users u ON u.uploaded_avatar_id = uploads.id")
|
||||||
.joins("LEFT JOIN user_avatars ua ON (ua.gravatar_upload_id = uploads.id OR ua.custom_upload_id = uploads.id)")
|
.joins("LEFT JOIN user_avatars ua ON (ua.gravatar_upload_id = uploads.id OR ua.custom_upload_id = uploads.id)")
|
||||||
.joins("LEFT JOIN user_profiles up ON up.profile_background = uploads.url OR up.card_background = uploads.url")
|
.joins("LEFT JOIN user_profiles up ON up.profile_background = uploads.url OR up.card_background = uploads.url")
|
||||||
.joins("LEFT JOIN categories c ON c.logo_url = uploads.url OR c.background_url = uploads.url")
|
.joins("LEFT JOIN categories c ON c.uploaded_logo_id = uploads.id OR c.uploaded_background_id = uploads.id")
|
||||||
.where("pu.upload_id IS NULL")
|
.where("pu.upload_id IS NULL")
|
||||||
.where("u.uploaded_avatar_id IS NULL")
|
.where("u.uploaded_avatar_id IS NULL")
|
||||||
.where("ua.gravatar_upload_id IS NULL AND ua.custom_upload_id IS NULL")
|
.where("ua.gravatar_upload_id IS NULL AND ua.custom_upload_id IS NULL")
|
||||||
.where("up.profile_background IS NULL AND up.card_background IS NULL")
|
.where("up.profile_background IS NULL AND up.card_background IS NULL")
|
||||||
.where("c.logo_url IS NULL AND c.background_url IS NULL")
|
.where("c.uploaded_logo_id IS NULL AND c.uploaded_background_id IS NULL")
|
||||||
.where("uploads.url NOT IN (?)", ignore_urls)
|
.where("uploads.url NOT IN (?)", ignore_urls)
|
||||||
|
|
||||||
result.find_each do |upload|
|
result.find_each do |upload|
|
||||||
|
|
|
@ -15,6 +15,8 @@ class Category < ActiveRecord::Base
|
||||||
|
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
belongs_to :latest_post, class_name: "Post"
|
belongs_to :latest_post, class_name: "Post"
|
||||||
|
belongs_to :uploaded_logo, class_name: "Upload"
|
||||||
|
belongs_to :uploaded_background, class_name: "Upload"
|
||||||
|
|
||||||
has_many :topics
|
has_many :topics
|
||||||
has_many :category_users
|
has_many :category_users
|
||||||
|
@ -38,9 +40,6 @@ class Category < ActiveRecord::Base
|
||||||
|
|
||||||
validate :email_in_validator
|
validate :email_in_validator
|
||||||
|
|
||||||
validates :logo_url, upload_url: true, if: :logo_url_changed?
|
|
||||||
validates :background_url, upload_url: true, if: :background_url_changed?
|
|
||||||
|
|
||||||
validate :ensure_slug
|
validate :ensure_slug
|
||||||
before_save :apply_permissions
|
before_save :apply_permissions
|
||||||
before_save :downcase_email
|
before_save :downcase_email
|
||||||
|
|
|
@ -49,7 +49,13 @@ class CategoryList
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_categories
|
def find_categories
|
||||||
@categories = Category.includes(:topic_only_relative_url, subcategories: [:topic_only_relative_url]).secured(@guardian)
|
@categories = Category.includes(
|
||||||
|
:uploaded_background,
|
||||||
|
:uploaded_logo,
|
||||||
|
:topic_only_relative_url,
|
||||||
|
subcategories: [:topic_only_relative_url]
|
||||||
|
).secured(@guardian)
|
||||||
|
|
||||||
@categories = @categories.where(suppress_from_homepage: false) if @options[:is_homepage]
|
@categories = @categories.where(suppress_from_homepage: false) if @options[:is_homepage]
|
||||||
@categories = @categories.where("categories.parent_category_id = ?", @options[:parent_category_id].to_i) if @options[:parent_category_id].present?
|
@categories = @categories.where("categories.parent_category_id = ?", @options[:parent_category_id].to_i) if @options[:parent_category_id].present?
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ class Site
|
||||||
def categories
|
def categories
|
||||||
@categories ||= begin
|
@categories ||= begin
|
||||||
categories = Category
|
categories = Category
|
||||||
|
.includes(:uploaded_logo, :uploaded_background)
|
||||||
.secured(@guardian)
|
.secured(@guardian)
|
||||||
.joins('LEFT JOIN topics t on t.id = categories.topic_id')
|
.joins('LEFT JOIN topics t on t.id = categories.topic_id')
|
||||||
.select('categories.*, t.slug topic_slug')
|
.select('categories.*, t.slug topic_slug')
|
||||||
|
|
|
@ -11,8 +11,6 @@ class BasicCategorySerializer < ApplicationSerializer
|
||||||
:description,
|
:description,
|
||||||
:description_text,
|
:description_text,
|
||||||
:topic_url,
|
:topic_url,
|
||||||
:logo_url,
|
|
||||||
:background_url,
|
|
||||||
:read_restricted,
|
:read_restricted,
|
||||||
:permission,
|
:permission,
|
||||||
:parent_category_id,
|
:parent_category_id,
|
||||||
|
@ -23,6 +21,9 @@ class BasicCategorySerializer < ApplicationSerializer
|
||||||
:sort_order,
|
:sort_order,
|
||||||
:sort_ascending
|
:sort_ascending
|
||||||
|
|
||||||
|
has_one :uploaded_logo, embed: :object, serializer: CategoryUploadSerializer
|
||||||
|
has_one :uploaded_background, embed: :object, serializer: CategoryUploadSerializer
|
||||||
|
|
||||||
def include_parent_category_id?
|
def include_parent_category_id?
|
||||||
parent_category_id
|
parent_category_id
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
class CategoryUploadSerializer < ApplicationSerializer
|
||||||
|
attributes :id, :url
|
||||||
|
end
|
|
@ -0,0 +1,21 @@
|
||||||
|
class AddUploadsToCategories < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
add_column :categories, :uploaded_logo_id, :integer, index: true
|
||||||
|
add_column :categories, :uploaded_background_id, :integer, index: true
|
||||||
|
|
||||||
|
transaction do
|
||||||
|
Category.find_each do |category|
|
||||||
|
logo_upload = Upload.find_by(url: category.logo_url)
|
||||||
|
category.uploaded_logo_id = logo_upload.id if logo_upload
|
||||||
|
|
||||||
|
background_upload = Upload.find_by(url: category.background_url)
|
||||||
|
category.uploaded_background_id = background_upload.id if background_upload
|
||||||
|
|
||||||
|
category.save!
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
remove_column :categories, :logo_url, :string
|
||||||
|
remove_column :categories, :background_url, :string
|
||||||
|
end
|
||||||
|
end
|
|
@ -24,7 +24,7 @@ module ImportExport
|
||||||
|
|
||||||
|
|
||||||
CATEGORY_ATTRS = [:id, :name, :color, :created_at, :user_id, :slug, :description, :text_color,
|
CATEGORY_ATTRS = [:id, :name, :color, :created_at, :user_id, :slug, :description, :text_color,
|
||||||
:auto_close_hours, :logo_url, :background_url, :auto_close_based_on_last_post,
|
:auto_close_hours, :auto_close_based_on_last_post,
|
||||||
:topic_template, :suppress_from_homepage, :permissions_params]
|
:topic_template, :suppress_from_homepage, :permissions_params]
|
||||||
|
|
||||||
def export_categories
|
def export_categories
|
||||||
|
|
|
@ -23,7 +23,7 @@ class DiscourseSassImporter < Sass::Importers::Filesystem
|
||||||
"plugins_desktop" => DiscoursePluginRegistry.desktop_stylesheets,
|
"plugins_desktop" => DiscoursePluginRegistry.desktop_stylesheets,
|
||||||
"plugins_variables" => DiscoursePluginRegistry.sass_variables,
|
"plugins_variables" => DiscoursePluginRegistry.sass_variables,
|
||||||
"theme_variables" => [ColorScheme::BASE_COLORS_FILE],
|
"theme_variables" => [ColorScheme::BASE_COLORS_FILE],
|
||||||
"category_backgrounds" => Proc.new { |c| "body.category-#{c.full_slug} { background-image: url(#{apply_cdn(c.background_url)}) }\n" }
|
"category_backgrounds" => Proc.new { |c| "body.category-#{c.full_slug} { background-image: url(#{apply_cdn(c.uploaded_background.url)}) }\n" }
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -53,8 +53,8 @@ class DiscourseSassImporter < Sass::Importers::Filesystem
|
||||||
end
|
end
|
||||||
when "category_backgrounds"
|
when "category_backgrounds"
|
||||||
contents = ""
|
contents = ""
|
||||||
Category.where('background_url IS NOT NULL').each do |c|
|
Category.where('uploaded_background_id IS NOT NULL').each do |c|
|
||||||
contents << special_imports[name].call(c) if c.background_url.present?
|
contents << special_imports[name].call(c) if c.uploaded_background
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
stylesheets = special_imports[name]
|
stylesheets = special_imports[name]
|
||||||
|
|
|
@ -160,7 +160,7 @@ class DiscourseStylesheets
|
||||||
def digest
|
def digest
|
||||||
@digest ||= begin
|
@digest ||= begin
|
||||||
theme = (cs = ColorScheme.enabled) ? "#{cs.id}-#{cs.version}" : false
|
theme = (cs = ColorScheme.enabled) ? "#{cs.id}-#{cs.version}" : false
|
||||||
category_updated = Category.where("background_url IS NOT NULL and background_url != ''").last_updated_at
|
category_updated = Category.where("uploaded_background_id IS NOT NULL").last_updated_at
|
||||||
|
|
||||||
if theme || category_updated > 0
|
if theme || category_updated > 0
|
||||||
Digest::SHA1.hexdigest "#{RailsMultisite::ConnectionManagement.current_db}-#{theme}-#{DiscourseStylesheets.last_file_updated}-#{category_updated}"
|
Digest::SHA1.hexdigest "#{RailsMultisite::ConnectionManagement.current_db}-#{theme}-#{DiscourseStylesheets.last_file_updated}-#{category_updated}"
|
||||||
|
|
|
@ -55,7 +55,7 @@ describe Jobs::CleanUpUploads do
|
||||||
|
|
||||||
it "does not delete category logo uploads" do
|
it "does not delete category logo uploads" do
|
||||||
category_logo_upload = fabricate_upload
|
category_logo_upload = fabricate_upload
|
||||||
Fabricate(:category, logo_url: category_logo_upload.url)
|
Fabricate(:category, uploaded_logo: category_logo_upload)
|
||||||
|
|
||||||
Jobs::CleanUpUploads.new.execute(nil)
|
Jobs::CleanUpUploads.new.execute(nil)
|
||||||
|
|
||||||
|
@ -64,13 +64,13 @@ describe Jobs::CleanUpUploads do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not delete category background url uploads" do
|
it "does not delete category background url uploads" do
|
||||||
category_background_url = fabricate_upload
|
category_logo_upload = fabricate_upload
|
||||||
Fabricate(:category, background_url: category_background_url.url)
|
Fabricate(:category, uploaded_background: category_logo_upload)
|
||||||
|
|
||||||
Jobs::CleanUpUploads.new.execute(nil)
|
Jobs::CleanUpUploads.new.execute(nil)
|
||||||
|
|
||||||
expect(Upload.find_by(id: @upload.id)).to eq(nil)
|
expect(Upload.find_by(id: @upload.id)).to eq(nil)
|
||||||
expect(Upload.find_by(id: category_background_url.id)).to eq(category_background_url)
|
expect(Upload.find_by(id: category_logo_upload.id)).to eq(category_logo_upload)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not delete post uploads" do
|
it "does not delete post uploads" do
|
||||||
|
|
|
@ -12,24 +12,6 @@ describe Category do
|
||||||
is_expected.to validate_uniqueness_of(:name).scoped_to(:parent_category_id)
|
is_expected.to validate_uniqueness_of(:name).scoped_to(:parent_category_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
context "url validation" do
|
|
||||||
let(:user) { Fabricate(:user) }
|
|
||||||
|
|
||||||
let(:upload) { Fabricate(:upload) }
|
|
||||||
|
|
||||||
it "ensures logo_url is valid" do
|
|
||||||
expect(Fabricate.build(:category, user: user, logo_url: "---%")).not_to be_valid
|
|
||||||
expect(Fabricate.build(:category, user: user, logo_url: "http://example.com/made-up.jpg")).not_to be_valid
|
|
||||||
expect(Fabricate.build(:category, user: user, logo_url: upload.url)).to be_valid
|
|
||||||
end
|
|
||||||
|
|
||||||
it "ensures background_url is valid" do
|
|
||||||
expect(Fabricate.build(:category, user: user, background_url: ";test")).not_to be_valid
|
|
||||||
expect(Fabricate.build(:category, user: user, background_url: "http://example.com/no.jpg")).not_to be_valid
|
|
||||||
expect(Fabricate.build(:category, user: user, background_url: upload.url)).to be_valid
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'validates uniqueness in case insensitive way' do
|
it 'validates uniqueness in case insensitive way' do
|
||||||
Fabricate(:category, name: "Cats")
|
Fabricate(:category, name: "Cats")
|
||||||
cats = Fabricate.build(:category, name: "cats")
|
cats = Fabricate.build(:category, name: "cats")
|
||||||
|
|
Loading…
Reference in New Issue