<?php
/**
 * Component classes.
 *
 * @package BuddyPress
 * @subpackage Core
 * @since 1.5.0
 */

// Exit if accessed directly.
defined( 'ABSPATH' ) || exit;

if ( !class_exists( 'CommunityAlly_Groups_Setup' ) ) :
class CommunityAlly_Groups_Setup {
	const GROUPS_CUSTOM_POST_TYPE = 'ca_groups';
	const GROUPS_CUSTOM_POST_SLUG = 'groups';
	const GROUPS_ID_POST_META_KEY = 'communityally-group-id';

	const SINGLE_ACTIVITY_PREFIX = 'activity-';

	// <editor-fold defaultstate="collapsed" desc="Add Groups custom post type">
	public static function register_custom_post() {
		$content_type_labels = array(
			'name' => 'Groups',
			'singular_name' => 'Group',
			'add_new' => 'Add New',
			'add_new_item' => 'Add New Group',
			'edit_item' => 'Edit Group',
			'new_item' => 'New Group',
			'view_item' => 'View Group',
			'search_items' => 'Search Groups',
			'not_found' => 'No group found.',
			'not_found_in_trash' => 'No group found in Trash.',
			'parent_item_colon' => null,
			'all_items' => 'All Groups'
			);
		$content_type_options = array(
			'labels' => $content_type_labels,
			'description' => 'Groups to host discussions',
			'publicly_queryable' => true,
			'exclude_from_search' => true,
			'capability_type' => 'page',
			'capabilities' => array(
				'create_posts' => 'create_ca_groups',
				'delete_others_posts' => 'delete_ca_groups',
			),
			'map_meta_cap' => true,
			'hierarchical' => true,
			'public' => true,
			'rewrite' => array('slug' => self::GROUPS_CUSTOM_POST_SLUG, 'with_front' => false, 'pages' => false),
			'has_archive' => false,
			'query_var' => true,
			'supports' => array('title', 'editor'),
			'taxonomies' => array(),
			'show_ui' => true,
			'menu_position' => null,
			'permalink_epmask' => EP_PERMALINK,
			'can_export' => true,
			'show_in_rest' => true,
			'show_in_nav_menus' => true,
			'show_in_menu' => true,
			'show_in_admin_bar' => null);

		register_post_type(self::GROUPS_CUSTOM_POST_TYPE, $content_type_options);
	}
	// </editor-fold>

	// <editor-fold defaultstate="collapsed" desc="Add actions">
	public static function add_actions() {
		add_action('add_meta_boxes', array(__CLASS__, 'add_template_select_meta_box'));
		add_action('save_post', array(__CLASS__, 'save_template_select_meta_box'));

		add_action('wp_ajax_communityally_group_get_member_list', array(__CLASS__, 'ajax_get_members_list'));
		add_action('wp_ajax_nopriv_communityally_group_get_member_list', array(__CLASS__, 'ajax_get_members_list'));

		add_action('wp_ajax_communityally_groups_edit_details', array(__CLASS__, 'ajax_update_group_details'));
		add_action('wp_ajax_communityally_group_upload_cover_image', array(__CLASS__, 'ajax_upload_cover_image'));
		add_action('wp_ajax_communityally_group_delete_cover_image', array(__CLASS__, 'ajax_delete_cover_image'));

		add_action('wp_ajax_communityally_groups_add_child_group', array(__CLASS__, 'ajax_add_child_group'));
		add_action('wp_ajax_communityally_groups_edit_child_group', array(__CLASS__, 'ajax_edit_child_group'));
		add_action('wp_ajax_communityally_groups_delete_child_group', array(__CLASS__, 'ajax_delete_child_group'));
	}
	// </editor-fold>

	// <editor-fold defaultstate="collapsed" desc="Add shortcodes">
	public static function add_shortcodes() {
		add_shortcode('communityally_group', array(__CLASS__, 'shortcode_communityally_group_abbreviated'));
		add_shortcode('communityally_group_display', array(__CLASS__, 'shortcode_communityally_group_display'));
	}
	// </editor-fold>

	// <editor-fold defaultstate="collapsed" desc="Check if current page is the Group custom post">
	public static function is_group_custom_post() {
		return is_singular(array(self::GROUPS_CUSTOM_POST_TYPE));
	}
	// </editor-fold>

	// <editor-fold defaultstate="collapsed" desc="Check if current page is the Feeds tab on a Group custom post">
	public static function is_group_subpage_selected($target_subpage) {
		$subpage = self::get_selected_subpage();
		return $target_subpage === $subpage;
	}
	// </editor-fold>

	// <editor-fold defaultstate="collapsed" desc="Retrieve the group ID associated with a custom post">
	public static function get_custom_post_group_id($post_id = false) {
		if (empty($post_id)) {
			$post_id = get_the_ID();
		}
		$group_id = get_post_meta($post_id, self::GROUPS_ID_POST_META_KEY, true);
		return $group_id;
	}
	// </editor-fold>

	// <editor-fold defaultstate="collapsed" desc="Retrieve the post ID associated with a group">
	private static $cached_group_post_mapping = array();
	public static function get_group_custom_post_id($group_id) {
		global $wpdb;
		if (isset(self::$cached_group_post_mapping[$group_id])) {
			return self::$cached_group_post_mapping[$group_id];
		}
		$query = $wpdb->prepare("SELECT * FROM {$wpdb->postmeta} WHERE meta_key = %s AND meta_value = %s", self::GROUPS_ID_POST_META_KEY, intval($group_id));
		$row = $wpdb->get_row($query);
		if (empty($row)) {
			return 0;
		}
		$post_id = $row->post_id;
		self::$cached_group_post_mapping[$group_id] = $post_id;
		return $post_id;
	}
	// </editor-fold>

	// <editor-fold defaultstate="collapsed" desc="Render group content">
	public static function shortcode_communityally_group_display($atts) {
		extract(shortcode_atts(array(
			'group_id' => '',
			'tab' => '',
		), $atts, 'communityally_group_display'));
		return self::render_group_content($group_id, $tab, false);
	}
	private static function get_show_single_activity_id($subpage = false) {
		if (false === $subpage) {
			$subpage = get_query_var('ca_subpage');
		}
		if (0 === strpos($subpage, self::SINGLE_ACTIVITY_PREFIX)) {
			return intval(substr($subpage, strlen(self::SINGLE_ACTIVITY_PREFIX)));
		}
		return false;
	}
	private static function get_selected_subpage($subpage = false, $group_id = false) {
		if (empty($subpage)) {
			$subpage = get_query_var('ca_subpage');
		}
		if (self::get_show_single_activity_id($subpage) > 0) {
			$subpage = 'activity';
		}

		// these are the only valid subpages
		if (!in_array($subpage, array('activity', 'discussion', 'members', 'admin', 'group-cover-image'))) {
			$subpage = 'activity';
		}
		// check for admin permission and render admin subpage only for admins
		if ($group_id && 'admin' === $subpage && !self::can_user_access_group_admin()) {
			$subpage = 'activity';
		}
		return $subpage;
	}
	public static function render_group_content($group_id, $subpage = false, $show_abbreviated = false) {
		if (empty($group_id)) {
			$post_id = get_the_ID();
			$group_id = self::get_custom_post_group_id($post_id);
		} else {
			$post_id = self::get_group_custom_post_id($group_id);
		}
		if (empty($post_id)) {
			return '';
		}
		if (empty($group_id)) {
			return '';
		}
		$group = groups_get_group($group_id);
		if (empty($group) || empty($group->id)) {
			return '';
		}
		$subpage = self::get_selected_subpage($subpage, $group_id);

		$base_url = trailingslashit(get_permalink($post_id));
		$nav_items = self::get_nav_items($post_id, $group_id, $subpage, $base_url);

		$ajax_url = admin_url('admin-ajax.php', 'relative');

		$args = array(
			'group_id' => $group_id,
			'base_url' => $base_url,
			'ajax_url' => $ajax_url,
			'activity_to_show' => self::get_show_single_activity_id(),
			);
		$template_file = 'home.php';
		if ($group->parent_id > 0) {	// this is a discussion page
			$template_file = 'discussion.php';
		} elseif ($show_abbreviated) {	// if not discussion, then just show the content
			$template_file = 'abbreviated.php';
		}
		ob_start();
		include (dirname(__FILE__) . '/template/' . $template_file);
		// Get the output buffer contents.
		$content = ob_get_clean();
		return $content;
	}
	// </editor-fold>

	// <editor-fold defaultstate="collapsed" desc="Get permalink for group">
	public static function shortcode_communityally_group_abbreviated($atts) {
		extract(shortcode_atts(array(
			'group_id' => '',
			'tab' => '',
		), $atts, 'communityally_group'));
		return self::render_group_content($group_id, $tab, true);
	}
	// </editor-fold>

	// <editor-fold defaultstate="collapsed" desc="Get permalink for group">
	public static function get_group_permalink($group_id) {
		$post_id = self::get_group_custom_post_id($group_id);
		if (empty($post_id)) {
			return '';
		}
		return trailingslashit(get_permalink($post_id));
	}
	// </editor-fold>

	// <editor-fold defaultstate="collapsed" desc="Add custom post rewrite rules">
	public static function add_rewrite_rules() {
		add_rewrite_rule('^groups/([^/]*)/([^/]+)/?$', 'index.php?post_type=ca_groups&ca_groups=$matches[1]&ca_subpage=$matches[2]', 'top');
	}
	// </editor-fold>

	// <editor-fold defaultstate="collapsed" desc="Generate group navigation items">
	private static function get_nav_items($post_id, $group_id, $subpage, $group_link) {
		$result = array(
				'activity' => array(
					'name' =>  __('Feed', 'communityally'),
					'url' => $group_link,
				),
			);

		$group = groups_get_group($group_id);

		$current_user_id = get_current_user_id();
		// Add group discussions tab
		if (!communityally_current_group_is_child_group($group)) { // do not display Discussion on child groups
			$result['discussion'] = array(
				'name' =>  __('Discussions', 'communityally'),
				'url' => $group_link . 'discussion/',
				);
		}
		$result['members'] = array(
			'name' => _x( 'Members', 'My Group screen nav', 'buddypress' ),
			'url' => $group_link . 'members/'
			);
		if (self::can_user_access_group_admin($current_user_id)) { // show admin tab only to admin users
			$result['admin'] = array(
				'name' => _x( 'Settings', 'Group screen nav', 'buddypress' ),
				'url' => $group_link . 'admin/'
				);
			if ('group-cover-image' === $subpage) {
				$subpage = 'admin';
			}
		}
		if (isset($result[$subpage])) {
			$result[$subpage]['selected'] = true;
		}
		return $result;
	}
	// </editor-fold>

	// <editor-fold defaultstate="collapsed" desc="Save group admin settings">
	public static function ajax_update_group_details() {
		if (!isset($_REQUEST['group_id'])) {
			bp_core_redirect(get_bloginfo('wpurl'));
		}
		$group_id = intval($_REQUEST['group_id']);
		$group_admin_url = CommunityAlly_Groups_Setup::get_group_permalink($group_id);
		$group_admin_url .= 'admin/';
		if (!isset($_REQUEST['group-name']) || !isset($_REQUEST['group-desc']) || !isset($_REQUEST['group-template']) || !isset($_REQUEST['nonce']) ||
			!wp_verify_nonce($_REQUEST['nonce'], 'communityally-groups-edit-details-' . $group_id)) {
			bp_core_redirect($group_admin_url);
		}

		// Name is required and may not be empty.
		if (empty($_POST['group-name'])) {
			bp_core_add_message( __( 'Groups must have a name. Please try again.', 'communityally' ), 'error' );
		} elseif (!groups_edit_base_group_details(array(
			'group_id' => $group_id,
			'name' => $_REQUEST['group-name'],
			'description' => $_REQUEST['group-desc'],
			'template' => $_REQUEST['group-template'],
		))) {
			bp_core_add_message(__( 'There was an error updating group details. Please try again.', 'buddypress'), 'error');
		} else {
			bp_core_add_message(__( 'Group details were successfully updated.', 'buddypress'));
		}

		bp_core_redirect($group_admin_url);
	}
	// </editor-fold>

	// <editor-fold defaultstate="collapsed" desc="Upload group cover image">
	public static function ajax_upload_cover_image() {
		if (!bp_is_post_request()) {
			wp_die();
		}

		check_admin_referer( 'bp-uploader' );
		if (!isset($_POST['group_id'])) {
			wp_die();
		}

		$group_id = intval($_POST['group_id']);

		// Sending the json response will be different if the current Plupload runtime is html4.
		$is_html4 = ! empty( $_POST['html4' ] );

		$cover_image_attachment = new BP_Attachment_Cover_Image(array(
			'action' => 'communityally_group_upload_cover_image',
			'object' => 'groups',
			'object_id' => $group_id,
		));
		$uploaded = $cover_image_attachment->upload( $_FILES );

		if ( ! empty( $uploaded['error'] ) ) {
			// Upload error response.
			bp_attachments_json_response( false, $is_html4, array(
				'type'    => 'upload_error',
				'message' => sprintf(
					/* translators: %s: the upload error message */
					__( 'Upload Failed! Error was: %s', 'buddypress' ),
					$uploaded['error']
				),
			) );
		}

		$error_message = __( 'There was a problem uploading the cover image.', 'buddypress' );

		$upload_dir = $cover_image_attachment->upload_dir_filter();

		$cover_dir = $upload_dir['path'];

		if ( 1 === validate_file( $cover_dir ) || ! is_dir( $cover_dir ) ) {
			// Upload error response.
			bp_attachments_json_response( false, $is_html4, array(
				'type'    => 'upload_error',
				'message' => $error_message,
			) );
		}

		/*
		 * Generate the cover image so that it fit to feature's dimensions
		 *
		 * Unlike the avatar, uploading and generating the cover image is happening during
		 * the same Ajax request, as we already instantiated the BP_Attachment_Cover_Image
		 * class, let's use it.
		 */
		$cover = bp_attachments_cover_image_generate_file( array(
			'file'            => $uploaded['file'],
			'component'       => 'groups',
			'cover_image_dir' => $cover_dir
		), $cover_image_attachment );

		if ( ! $cover ) {
			bp_attachments_json_response( false, $is_html4, array(
				'type'    => 'upload_error',
				'message' => $error_message,
			) );
		}

		$cover_url = $upload_dir['url'] . '/' . $cover['cover_basename'];

		// Set the name of the file.
		$name       = $_FILES['file']['name'];
		$name_parts = pathinfo( $name );
		$name       = trim( substr( $name, 0, - ( 1 + strlen( $name_parts['extension'] ) ) ) );

		// Finally return the cover image url to the UI.
		bp_attachments_json_response( true, $is_html4, array(
			'name'          => $name,
			'url'           => $cover_url,
		) );
	}
	// </editor-fold>

	// <editor-fold defaultstate="collapsed" desc="Delete group cover image">
	public static function ajax_delete_cover_image() {
		if (!bp_is_post_request()) {
			wp_die();
		}

		if (empty($_POST['group_id']) || empty($_POST['delete_nonce']) ||
			!wp_verify_nonce($_POST['delete_nonce'], 'communityally-delete-cover-image-' . $_POST['group_id'])) {
			wp_send_json_error();
		}

		$group_id = intval($_POST['group_id']);
		$args = array(
			'object'  => 'group',
			'item_id' => $group_id,
		);

		if ( ! bp_attachments_current_user_can( 'edit_cover_image', $args ) ) {
			wp_send_json_error();
		}

		// Handle delete.
		if (bp_attachments_delete_file(array('item_id' => $group_id, 'object_dir' => 'groups', 'type' => 'cover-image'))) {
			$response = array(
				'feedback_code' => 3,
			);

			wp_send_json_success($response);
		} else {
			wp_send_json_error( array(
				'feedback_code' => 2,
			) );
		}
	}
	// </editor-fold>

	// <editor-fold defaultstate="collapsed" desc="Create custom post for a group>
	public static function create_custom_post_for_group($group) {
		$is_block_editor = function_exists('register_block_type');
		$new_post_param = array(
			'post_title' => $group->name,
			'post_name' => $group->slug,
			'post_type' => self::GROUPS_CUSTOM_POST_TYPE,
			'post_status' => 'publish',
			'post_author' => 0,	// custom post without an author can't be deleted in the interface
			);
		if ($is_block_editor) {
			$new_post_param['post_content'] = '<!-- wp:accessally-gutenberg/shortcode {"shortcode_type":"communityally-group-display","current_post_id":"0","param_14":"0"} /-->';
		} else {
			$new_post_param['post_content'] = '[communityally_group_display]';
		}

		$post_id = wp_insert_post($new_post_param);
		if (!is_wp_error($post_id)) {
			update_post_meta($post_id, self::GROUPS_ID_POST_META_KEY, $group->id);
		}
		return $post_id;
	}
	// </editor-fold>

	// <editor-fold defaultstate="collapsed" desc="Convert legacy BP groups to new custom posts">
	public static function convert_legacy_groups_to_custom_posts() {
		$all_groups = groups_get_groups(array('per_page' => null));	// get all groups

		$all_groups_with_tag_access = groups_with_groupmeta(META_KEY_COMMUNITY_ALLY_GROUP_PERMISSION);
		$group_permissions = array();
		foreach ($all_groups_with_tag_access as $entry) {
			$group_permissions[$entry->group_id] = unserialize($entry->meta_value);
		}

		$all_groups_offering_key = groups_with_groupmeta(META_KEY_COMMUNITY_ALLY_GROUP_OFFERING_KEY);
		$group_offering_key = array();
		foreach ($all_groups_offering_key as $entry) {
			$group_offering_key[$entry->group_id] = $entry->meta_value;
		}
		foreach ($all_groups['groups'] as $group) {
			$post_id = self::create_custom_post_for_group($group);
			if (!is_wp_error($post_id)) {
				$template_key = groups_get_groupmeta($group->id, 'theme_template');
				if (!empty($template_key)) {
					update_post_meta($post_id, '_wp_page_template', $template_key);
				}
				if (!empty($group_permissions[$group->id])) {
					update_post_meta($post_id, '_accessally_post_permission', $group_permissions[$group->id]);
				}
				if (!empty($group_offering_key[$group->id])) {
					update_post_meta($post_id, '_accessally_course_key', $group_offering_key[$group->id]);
				}
			}
		}
	}
	// </editor-fold>

	// <editor-fold defaultstate="collapsed" desc="Register template select meta box for the Group custom post">
	public static function delete_individual_group($group_id) {
		groups_delete_group($group_id);
		$group_post_id = self::get_group_custom_post_id($group_id);
		wp_delete_post($group_post_id);

		do_action('groups_group_deleted', $group_id);
	}
	// </editor-fold>

	// <editor-fold defaultstate="collapsed" desc="Register template select meta box for the Group custom post">
	public static function add_template_select_meta_box(){
		global $post;
		if (self::GROUPS_CUSTOM_POST_TYPE === $post->post_type) {
			add_meta_box('communityally_template_select_div', __('Template'), array(__CLASS__, 'custom_page_attributes_meta_box'), NULL, 'side', 'core');
		}
	}

	public static function custom_page_attributes_meta_box($post) {
		$template = get_post_meta( $post->ID, '_wp_page_template', 1 );
		$default_title = apply_filters('default_page_template_title',  __('Default Template'), 'meta-box' );
		echo '<select name="page_template"><option>';
		echo esc_html($default_title);
		echo '</option>';
		page_template_dropdown($template);
		echo '</select>';
	}

	public static function save_template_select_meta_box( $post_id ) {
		if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
			return;
		}
		if (empty($_POST['post_type']) || self::GROUPS_CUSTOM_POST_TYPE !== $_POST['post_type']) {
			return;
		}
		if (!current_user_can('edit_post', $post_id)) {
			return;
		}
		if (!empty($_POST['page_template'])) {
			update_post_meta($post_id, '_wp_page_template', $_POST['page_template']);
		}
	}
	// </editor-fold>

	// <editor-fold defaultstate="collapsed" desc="Ajax: get members list">
	public static function ajax_get_members_list() {
		$result = array(
			'status' => 'error',
			'message' => 'Please refresh the page and retry.',
			);
		try {
			if (!isset($_POST['group_id']) || !isset($_POST['nonce']) ||
				!wp_verify_nonce($_POST['nonce'], 'communityally-update')) {
				throw new Exception('Missing parameter.');
			}
			$group_id = intval($_POST['group_id']);
			$args = array(
				'page' => 1,
				'group_id' => $group_id,
			);
			if (isset($_POST['page'])) {
				// the page string is prefixed with #
				$page_str = str_replace('#', '', $_POST['page']);
				$args['page'] = max(1, intval($page_str));
			}

			if (!empty($_POST['order'])) {
				$args['type'] = $_POST['order'];
				$args['action'] = $_POST['order'];
			}

			if (!empty($_POST['search'])) {
				$args['search_terms'] = $_POST['search'];
			}

			$members_content = communityally_activity_template_loader('members', '', 'group_members', $args);
			$code = $members_content['contents'];

			$result = array('status' => 'success', 'code' => $code);
		} catch (Exception $e) {
			$result['status'] = 'error';
			$result['message'] = $e->getMessage();
		}
		echo json_encode($result);
		die();
	}
	// </editor-fold>

	// <editor-fold defaultstate="collapsed" desc="Ajax: add child discussion">
	public static function ajax_add_child_group() {
		$result = array(
			'status' => 'error',
			'message' => 'Please refresh the page and retry.',
			);
		try {
			if (!bp_user_can_create_groups() || !isset($_POST['group_id']) || !isset($_POST['details']) || !isset($_POST['nonce']) ||
				!wp_verify_nonce($_POST['nonce'], 'communityally-update')) {
				throw new Exception('Missing parameter.');
			}
			$group_settings = CommunityAllyUtilities::convert_setting_string_to_array(stripslashes($_POST['details']));

			$parent_group_id = intval($_POST['group_id']);
			$group_param = array(
				'group_id'     => 0,
				'creator_id'   => get_current_user_id(),
				'name'         => $group_settings['title'],
				'description'  => $group_settings['description'],
				'slug'         => '',
				'status'       => 'private',
				'parent_id'    => $parent_group_id,
				'enable_forum' => null,
				'date_created' => null
			);
			$group_id = groups_create_group($group_param);
			$group = groups_get_group($group_id);
			$group_post_id = self::create_custom_post_for_group($group);

			// clone the parent permission to the discussion
			$parent_group_post_id = self::get_group_custom_post_id($parent_group_id);
			$parent_permission = apply_filters('accessally_get_page_permission', array(), $parent_group_post_id);
			apply_filters('accessally_set_page_permission', $parent_permission, $group_post_id);

			$code = communityally_get_child_group_list_display($parent_group_id);

			$result = array('status' => 'success', 'code' => $code);
		} catch (Exception $e) {
			$result['status'] = 'error';
			$result['message'] = $e->getMessage();
		}
		echo json_encode($result);
		die();
	}
	// </editor-fold>

	// <editor-fold defaultstate="collapsed" desc="Ajax: edit child discussion details">
	public static function ajax_edit_child_group() {
		$result = array(
			'status' => 'error',
			'message' => 'Please refresh the page and retry.',
			);
		try {
			if (!(bp_current_user_can( 'bp_moderate' ) || bp_group_is_admin()) || !isset($_POST['group_id']) ||
				!isset($_POST['parent_id']) || !isset($_POST['details']) || !isset($_POST['nonce']) ||
				!wp_verify_nonce($_POST['nonce'], 'communityally-update')) {
				throw new Exception('Missing parameter.');
			}

			$group_settings = CommunityAllyUtilities::convert_setting_string_to_array(stripslashes($_POST['details']));

			// this logic is the mirror of groups_screen_group_admin_edit_details
			if (empty($group_settings['title'])) {
				throw new Exception(__('Discussions must have a name. Please try again.', 'communityally'));
			}

			$edit_group_is_success = groups_edit_base_group_details(array(
				'group_id' => intval($_POST['group_id']),
				'name' => sanitize_text_field($group_settings['title']),
				'description' => sanitize_text_field($group_settings['description']),
				));

			if (!$edit_group_is_success) {
				throw new Exception(__('There was an error updating the discussion. Please try again.', 'communityally'));
			}

			$parent_group_id = intval($_POST['parent_id']);
			$code = communityally_get_child_group_list_display($parent_group_id);

			$result = array('status' => 'success', 'code' => $code);
			$result['status'] = 'success';
		} catch (Exception $e) {
			$result['status'] = 'error';
			$result['message'] = $e->getMessage();
		}
		echo json_encode($result);
		die();
	}
	// </editor-fold>

	// <editor-fold defaultstate="collapsed" desc="Ajax: delete child discussion">
	public static function ajax_delete_child_group(){
		$result = array(
			'status' => 'error',
			'message' => 'Please refresh the page and retry.',
			);
		try {
			if (!(bp_current_user_can( 'bp_moderate' ) || bp_group_is_admin()) || !isset($_POST['group_id']) ||
				!isset($_POST['parent_id']) || !isset($_POST['nonce']) ||
				!wp_verify_nonce($_POST['nonce'], 'communityally-update')) {
				throw new Exception('Missing parameter.');
			}

			$group_id = intval($_POST['group_id']);
			$parent_group_id = intval($_POST['parent_id']);

			self::delete_individual_group($group_id);

			$code = communityally_get_child_group_list_display($parent_group_id);

			$result = array('status' => 'success', 'code' => $code);
		} catch (Exception $e) {
			$result['status'] = 'error';
			$result['message'] = $e->getMessage();
		}
		echo json_encode($result);
		die();
	}
	// </editor-fold>

	// <editor-fold defaultstate="collapsed" desc="Evaluate whether a user has permission to access a group based on the custom post permission">
	public static function can_user_view_group($group_id, $user_id = false) {
		if (false === $user_id) {
			$user_id = get_current_user_id();
		}
		$group_post_id = self::get_group_custom_post_id($group_id);
		$can_access = apply_filters('accessally_can_user_access_post', $group_post_id, $user_id);
		return $can_access;
	}
	private static function can_user_access_group_admin($user_id = false)
	{
		$user = $user_id ? get_user_by('ID', $user_id) : wp_get_current_user();
		$isAdmin = $user ? in_array('administrator', $user->roles, true) : false;
		return $isAdmin;
	}
	// </editor-fold>

	// <editor-fold defaultstate="collapsed" desc="Check if an activity and its children has a specific ID">
	public static function does_activity_has_id($activity, $target_id) {
		if (intval($activity->id) === $target_id) {
			return true;
		}
		if (!empty($activity->children)) {
			foreach ((array)$activity->children as $comment) {
				if (intval($comment->id) === $target_id) {
					return true;
				}
			}
		}
		return false;
	}
	// </editor-fold>
}
endif; // CommunityAlly_Groups_Setup.