Skip to content

Commit

Permalink
Merge pull request #172 from bcc-code/feature/extend-news-feeds
Browse files Browse the repository at this point in the history
  • Loading branch information
rvanoord authored Oct 16, 2024
2 parents 29bc5c6 + 4bd14da commit 7dbc0ee
Show file tree
Hide file tree
Showing 7 changed files with 6,353 additions and 4,194 deletions.
19 changes: 19 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "docker compose up",
"type": "shell",
"command": "docker compose up",
"problemMatcher": []
},
{
"label": "docker compose down",
"type": "shell",
"command": "docker compose down",
"problemMatcher": []
}
]
}
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# BCC WordPress Plugins

## Testing locally
1. Create a .env file (based on .env-example)
3. Build the frontend components: `yarn install && yarn build`
4. Run docker: `docker compose up`
5. Visit https://localhost:5001

5 changes: 0 additions & 5 deletions Testing bcc-login plugin locally.md

This file was deleted.

2 changes: 1 addition & 1 deletion plugins/bcc-login/bcc-login.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ private function __construct(){
$this->_users = new BCC_Login_Users($this->_settings);
$this->_visibility = new BCC_Login_Visibility( $this->_settings, $this->_client, $this->_coreapi );
$this->_widgets = new BCC_Login_Widgets( $this->_settings, $this->_client );
$this->_feed = new BCC_Login_Feed( $this->_settings, $this->_client );
$this->_feed = new BCC_Login_Feed( $this->_settings, $this->_client, $this->_visibility );
$this->_updater = new BCC_Login_Updater( $this->plugin, $this->plugin_slug, $this->plugin_version, $this->plugin_name );
$this->_notifications = new BCC_Notifications( $this->_settings, $this->_coreapi );

Expand Down
1 change: 1 addition & 0 deletions plugins/bcc-login/includes/class-bcc-coreapi-client.php
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ class Token_Response {
public $access_token;
public $scope;
public $expires_in;
public $token_type;
}

?>
178 changes: 174 additions & 4 deletions plugins/bcc-login/includes/class-bcc-login-feed.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,199 @@
class BCC_Login_Feed {
private BCC_Login_Settings $_settings;
private BCC_Login_Client $_client;
private BCC_Login_Visibility $_visibility;

function __construct( BCC_Login_Settings $settings, BCC_Login_Client $client ) {
function __construct( BCC_Login_Settings $settings, BCC_Login_Client $client, BCC_Login_Visibility $visibility ) {
$this->_settings = $settings;
$this->_client = $client;
add_filter('the_excerpt_rss', array( $this, 'add_image_to_rss' ));
add_filter( 'the_category_rss', array( $this, 'add_internal_category_to_member_posts'), 10, 2 );
add_filter( 'the_category_rss', array( $this, 'add_internal_category_to_member_items'), 10, 2 );
add_action('pre_get_posts', array( $this,'include_custom_post_types_in_feed'));
add_filter( 'rss2_ns', array( $this, 'add_custom_bcc_namespace'));
add_filter( 'rss2_item', array( $this, 'add_custom_elements_to_items'));
}

function add_custom_bcc_namespace() {
echo 'xmlns:bcc="https://developer.bcc.no/bcc-widgets/integration/news" ';
}

// Allow post_types to be specified via query string
function include_custom_post_types_in_feed($query) {
// Check if it's the main query and a feed
if ($query->is_main_query() && $query->is_feed()) {

// Check if the 'post_types' query parameter exists in the URL
if (isset($_GET['post_types'])) {
// Get the post types from the query string and split them by comma
$post_types = explode(',', sanitize_text_field($_GET['post_types']));
} else {
// Default post types if no query string is provided
$post_types = array('post');
}

// Modify the query to include the specified post types
$query->set('post_type', $post_types);
}
}


function add_image_to_rss($content) {
global $post;
if ( has_post_thumbnail( $post->ID ) )
$content = '<div>' . get_the_post_thumbnail( $post->ID, 'medium') . '</div>' . $content;
return $content;
}

function add_internal_category_to_member_posts($the_list, $type) {
function add_internal_category_to_member_items($the_list, $type) {
global $post;
$result = '';
$visibility = (int) get_post_meta( $post->ID, 'bcc_login_visibility', true );
if (!$visibility) {
$visibility = $this->_settings->default_visibility;
}
if ($visibility == BCC_Login_Visibility::VISIBILITY_MEMBER) {
return '<category>internal</category>';
$result = $result . "<category>internal</category>";
}
return $result;
}

function add_custom_elements_to_items($the_list){
$this->add_visibility_to_items($the_list);
$this->add_groups_to_items($the_list);
$this->add_post_type_to_items($the_list);
$this->add_original_language_to_items($the_list);
}

// Include basic visibility settings in feed:
// - public (no authentication required)
// - user (requires authentication)
// - internal:{district name} (requires affiliation with organization in specified district)
function add_visibility_to_items ($the_list) {
global $post;
$visibility = $this->_settings->default_visibility;
if ( $bcc_login_visibility = (int) get_post_meta( $post->ID, 'bcc_login_visibility', true ) ) {
$visibility = $bcc_login_visibility;
}
if ($visibility == BCC_Login_Visibility::VISIBILITY_PUBLIC){
echo "<bcc:visibility>public</bcc:visibility>\n";

} else if ($visibility == BCC_Login_Visibility::VISIBILITY_SUBSCRIBER){
echo "<bcc:visibility>user</bcc:visibility>\n";
} else if ($visibility == BCC_Login_Visibility::VISIBILITY_MEMBER){
echo "<bcc:visibility>internal:" . $this->_settings->member_organization_name . "</bcc:visibility>\n";
}
}

function array_union($x, $y)
{
if (empty($x) && empty($y)){
return [];
}
if (empty($x)){
return $y;
}
if (empty($y)){
return $x;
}
// Use array_merge to combine three arrays:
// 1. Intersection of $x and $y
// 2. Elements in $x that are not in $y
// 3. Elements in $y that are not in $x
$aunion = array_merge(
array_intersect($x, $y), // Intersection of $x and $y
array_diff($x, $y), // Elements in $x but not in $y
array_diff($y, $x) // Elements in $y but not in $x
);

// Return the resulting array representing the union
return $aunion;
}

// Include group uid for each group that the post is visible for or targetted at (notification group)
// E.g.
// <bcc:visiblityGroup>d4c434a7-504a-4246-9a10-def7dbfa982c</bcc:visiblityGroup>
// <bcc:visiblityGroup>25f5bc4d-48e0-4a6e-bf05-6b2a15d70861</bcc:visiblityGroup>
// <bcc:notificationGroup>d4c434a7-504a-4246-9a10-def7dbfa982c</bcc:notificationGroup>
function add_groups_to_items($the_list) {
global $post;
$result = '';
if ( !empty($this->_settings->site_groups) || !empty($this->_settings->full_content_access_groups) ) {
// Get groups that are checked on post
$post_groups = get_post_meta($post->ID, 'bcc_groups', false);

// Visiblity Groups: Groups that are checked on post + groups with access to all posts
$visibility_post_groups = $this->array_union($post_groups, $this->_settings->full_content_access_groups);
foreach ($visibility_post_groups as $group){
$result = $result . "\t\t<bcc:visibilityGroup>" . $group . "</bcc:visibilityGroup>\n";
}

if (in_array($post->post_type, $this->_settings->notification_post_types)){
// Notification Groups: Groups that are checked on posts + are eligable for notification
$notification_groups = array_intersect($post_groups, $this->_settings->notification_groups);
foreach ($notification_groups as $group){
$result = $result . "\t\t<bcc:notificationGroup>" . $group . "</bcc:notificationGroup>\n";
}
}

}
echo $result;
}

// Include post type element (e.g. <bcc:type>post</bcc:type>)
function add_post_type_to_items($the_list) {
global $post;
echo "\t\t<bcc:type>" . $post->post_type . "</bcc:type>\n";
}

function escape_xml($string) {
return htmlspecialchars($string, ENT_QUOTES | ENT_XML1, 'UTF-8');
}

// Add meta data relating to the orginal post (language). If this is the orginal,
// then the values will match the Guid, Url on the current item.
// Example:
// <bcc:translatedFrom language="no" guid="https://bcc.no/?p=2343" url="https://bcc.no/en-eller-annen-artikkel" title="Hello verden!" />
function add_original_language_to_items($the_list) {
global $post;
$post_type = get_post_type( $post );
$post_id = $post->ID;

$wpml_installed = defined('ICL_SITEPRESS_VERSION');

// 4. Handle multilingual posts (in WMPL)
if ($wpml_installed) {
// WPML is installed and active.

// Get default language for site
$current_language = ICL_LANGUAGE_CODE;

// Check if post has been translated
$has_translations = apply_filters('wpml_element_has_translations', '', $post_id, $post_type);
if ($has_translations) {

$is_multilinguage_post = true;
$trid = apply_filters('wpml_element_trid', NULL, $post_id, 'post_' . $post_type);
$translations = apply_filters('wpml_get_element_translations', NULL, $trid, 'post_' . $post_type);

foreach ($translations as $lang_code => $details) {
if ($details->element_id == $post_id) {
break; //Current post is original
}
if ($details->original == "1") {
// Another language is original
$original_post = get_post($details->element_id); // Get post object by ID
$original_post_guid = $original_post->guid; // Extract the GUID
do_action('wpml_switch_language', $lang_code);
$original_post_permalink = get_permalink($details->element_id);
do_action('wpml_switch_language', $current_language);

echo "\t\t<bcc:translatedFrom language=\"" . $lang_code . "\" guid=\"" . $this->escape_xml($original_post_guid) . "\" url=\"" . $this->escape_xml($original_post_permalink) . "\" title=\"" . $this->escape_xml($original_post->post_title) . "\"/>\n";

break;
}
}
}
}

}
}
Loading

0 comments on commit 7dbc0ee

Please sign in to comment.