discourse-adplugin/app/models/house_ad_setting.rb
Isaac Janzen 554f03f3da
FEATURE: Add group and category restrictions to house ads (#205)
# Description

This PR adds the ability to apply **group** and **category** restrictions to a **house ad**.

# What is included
- In order to get the group and category selectors to work within `admin/assets/javascripts/discourse/controllers/admin-plugins-house-ads-show.js` I needed to modernize the file. 
- I dropped the `bufferedProperty` implementation in favor of a vanilla ember approach
- I added `category_ids` and `group_ids` to our house ads model
- I added tests for group / category restrictions
- I added a preview button to display the house ad
- `/site.json` would return a object called `house_creatives` and a list of key value pairs that matched the ad name with the html, like so:
```js
{ AD_KEY: ad.html }
```
I need access to the category ids on the client to conditionally render the house ads so the new format will be: 
```js
{ AD_KEY: { html: ad.html, category_ids: ad.category_ids } }
```

# Screenshots
<img width="658" alt="Screenshot 2024-04-08 at 2 39 22 PM" src="https://github.com/discourse/discourse-adplugin/assets/50783505/b44b386d-65a1-4a2a-a487-d735b13357dd">

# Preview Video

https://github.com/discourse/discourse-adplugin/assets/50783505/6d0d8253-afef-4e15-b6fc-c6f696efd169
2024-04-09 11:54:11 -06:00

81 lines
2.3 KiB
Ruby

# frozen_string_literal: true
module ::AdPlugin
class HouseAdSetting
DEFAULTS = {
topic_list_top: "",
topic_above_post_stream: "",
topic_above_suggested: "",
post_bottom: "",
topic_list_between: "",
}
def self.all
settings = DEFAULTS.dup
PluginStoreRow
.where(plugin_name: AdPlugin.plugin_name)
.where("key LIKE 'ad-setting:%'")
.each { |psr| settings[psr.key[11..-1].to_sym] = psr.value }
settings
end
def self.settings_and_ads(for_anons: true, scope: nil)
settings = AdPlugin::HouseAdSetting.all
ad_names = settings.values.map { |v| v.split("|") }.flatten.uniq
if for_anons
ads = AdPlugin::HouseAd.all_for_anons
else
ads = AdPlugin::HouseAd.all_for_logged_in_users(scope)
end
ads = ads.select { |ad| ad_names.include?(ad.name) }
{
settings:
settings.merge(
after_nth_post: SiteSetting.house_ads_after_nth_post,
after_nth_topic: SiteSetting.house_ads_after_nth_topic,
house_ads_frequency: SiteSetting.house_ads_frequency,
),
creatives:
ads.inject({}) do |h, ad|
h[ad.name] = { html: ad.html, category_ids: ad.category_ids }
h
end,
}
end
def self.update(setting_name, value)
raise Discourse::NotFound unless DEFAULTS.keys.include?(setting_name.to_sym)
ad_names = value&.split("|") || []
raise Discourse::InvalidParameters if value && ad_names.any? { |v| v !~ HouseAd::NAME_REGEX }
ad_names = (HouseAd.all.map(&:name) & ad_names) unless ad_names.empty?
new_value = ad_names.join("|")
if value.nil? || new_value == DEFAULTS[setting_name.to_sym]
AdPlugin.pstore_delete("ad-setting:#{setting_name}")
else
AdPlugin.pstore_set("ad-setting:#{setting_name}", new_value)
end
Site.clear_anon_cache!
publish_settings
end
def self.publish_settings
MessageBus.publish("/site/house-creatives/anonymous", settings_and_ads(for_anons: true))
MessageBus.publish(
"/site/house-creatives/logged-in",
settings_and_ads(for_anons: false),
group_ids: [Group::AUTO_GROUPS[:trust_level_0]],
)
end
end
end