312 lines
9.6 KiB
PHP
312 lines
9.6 KiB
PHP
<?php
|
|
|
|
// Exit if accessed directly
|
|
defined( 'ABSPATH' ) || exit;
|
|
|
|
class Wiaas_User_Organization extends WP_User_Taxonomy {
|
|
|
|
const TAXONOMY_NAME = 'wiaas-user-organization';
|
|
const TAXONOMY_SLUG = 'users/wiaas-organization';
|
|
|
|
public function __construct()
|
|
{
|
|
$args = array(
|
|
'singular' => __('Organization', 'wiaas'),
|
|
'plural' => __('Organizations', 'wiaas'),
|
|
'exclusive' => true,
|
|
'public' => true,
|
|
'show_in_rest' => true,
|
|
'rest_base' => 'organization'
|
|
);
|
|
$labels = array();
|
|
$caps = array();
|
|
parent::__construct(self::TAXONOMY_NAME, self::TAXONOMY_SLUG, $args, $labels, $caps);
|
|
|
|
$this->hooks();
|
|
}
|
|
|
|
/**
|
|
* Add organization specific hooks
|
|
*/
|
|
function hooks() {
|
|
|
|
parent::hooks();
|
|
|
|
add_action('user_new_form', array( $this, 'show_organizations_selection' ));
|
|
add_action('user_register', array( $this, 'save_terms_for_user' ));
|
|
|
|
add_action( 'created_' . self::TAXONOMY_NAME, array( __CLASS__, 'on_organization_added' ));
|
|
add_action( 'pre_delete_term', array( __CLASS__, 'on_taxonomy_term_will_be_deleted' ), 10, 2);
|
|
add_action('set_object_terms', array( __CLASS__, 'on_taxonomy_term_assigned' ), 10, 4);
|
|
add_action('deleted_term_relationships', array( __CLASS__, 'on_taxonomy_term_unassigned' ), 10, 3);
|
|
}
|
|
|
|
// hooks functions
|
|
|
|
/**
|
|
* Creates corresponding access group for newly created organizational term
|
|
*
|
|
* @param $organization_id id of the organization term
|
|
*/
|
|
public static function on_organization_added($organization_id) {
|
|
self::_create_organization_access_group($organization_id);
|
|
}
|
|
|
|
/**
|
|
* Removes corresponding acces group when organization term is deleted
|
|
*
|
|
* @param $term_id - term id that will be deleted
|
|
* @param $taxonomy - taxonomy to which term belongs (in our case `user-organizations`)
|
|
*/
|
|
public static function on_taxonomy_term_will_be_deleted($term_id, $taxonomy) {
|
|
if ($taxonomy === self::TAXONOMY_NAME) {
|
|
$organization_id = $term_id;
|
|
self::_remove_organization_access_group($organization_id);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Adds user to corresponding access groups when he is assigned to organization.
|
|
* User will also be added to child organizations access groups.
|
|
*
|
|
* @param $object_id - id of object to which term is assigned (in our case $user_id)
|
|
* @param $terms - assigned terms (in our case $organizations)
|
|
* @param $tt_ids - assigned terms ids (in our case $organizations_ids)
|
|
* @param $taxonomy - taxonomy to which term belongs (in our case `user-organizations`)
|
|
*/
|
|
public static function on_taxonomy_term_assigned($object_id, $terms, $tt_ids, $taxonomy) {
|
|
if ($taxonomy === self::TAXONOMY_NAME) {
|
|
$user_id = $object_id;
|
|
$organization_id = $tt_ids[0];
|
|
add_user_meta($user_id, 'organization_id', $organization_id, true);
|
|
self::_add_user_to_access_group($user_id, $organization_id);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Removes user from corresponding access groups when he is removed from organization.
|
|
* User will also be removed from child organizations access groups.
|
|
*
|
|
* @param $object_id - id of object to which term is assigned (in our case $user_id)
|
|
* @param $tt_ids - assigned terms ids (in our case $organizations_ids)
|
|
* @param $taxonomy - taxonomy to which term belongs (in our case `user-organizations`)
|
|
*/
|
|
public static function on_taxonomy_term_unassigned($object_id, $tt_ids, $taxonomy) {
|
|
if ($taxonomy === self::TAXONOMY_NAME) {
|
|
$user_id = $object_id;
|
|
$organization_id = $tt_ids[0];
|
|
delete_user_meta($user_id, 'organization_id');
|
|
self::_remove_user_from_organization_access_groups($user_id, $organization_id);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Retrieves user organization based on user id
|
|
*
|
|
* @param null $user_id
|
|
* @return mixed
|
|
*/
|
|
public static function get_user_organization($user_id = null) {
|
|
if (!isset($user_id)) {
|
|
$user = wp_get_current_user();
|
|
$user_id = $user->ID;
|
|
}
|
|
$terms = wp_get_object_terms($user_id, self::TAXONOMY_NAME);
|
|
return $terms[0];
|
|
}
|
|
|
|
/**
|
|
* Assignees post to user organization. Post will be assigned to corresponding access groups.
|
|
* If user organization has parent organizations, staff from parent organizations will also be able
|
|
* to access order.
|
|
*
|
|
* @param $post_id - custom post id (product, order, ...)
|
|
* @param $user_id
|
|
*/
|
|
public static function assign_post_to_user_organization($post_id, $user_id) {
|
|
$organization = self::get_user_organization($user_id);
|
|
self::_assign_post_to_organization($post_id, $organization->term_id);
|
|
}
|
|
|
|
|
|
// private helper functions
|
|
|
|
/**
|
|
* Retrieves organization object based organization id
|
|
*
|
|
* @param $organization_id
|
|
* @return mixed
|
|
*/
|
|
private static function _get_organization_access_group_id($organization_id) {
|
|
return get_term_meta($organization_id, 'group_id', true);
|
|
}
|
|
|
|
/**
|
|
* Retrieves all access groups ids for organization. This includes corresponding access group
|
|
* for provided organization and also access groups for all of its child organizations.
|
|
*
|
|
* @param $organization_id
|
|
* @return array
|
|
*/
|
|
private static function _get_organization_all_access_groups_ids($organization_id) {
|
|
$access_groups_ids = array();
|
|
$access_groups_ids[] = self::_get_organization_access_group_id($organization_id);
|
|
$organization_departments_ids = self::_get_organization_departments_ids($organization_id);
|
|
foreach ($organization_departments_ids as $organization_department_id) {
|
|
$access_groups_ids[] = self::_get_organization_access_group_id($organization_department_id);
|
|
}
|
|
return $access_groups_ids;
|
|
}
|
|
|
|
/**
|
|
* Retrieves all departments of organization
|
|
*
|
|
* @param $organization_id
|
|
* @return array|WP_Error
|
|
*/
|
|
private static function _get_organization_departments_ids($organization_id) {
|
|
return get_term_children($organization_id, self::TAXONOMY_NAME);
|
|
}
|
|
|
|
/**
|
|
* Assign custom post to corresponding organizational acccess group.
|
|
*
|
|
* @param $post_id
|
|
* @param $organization_id
|
|
*/
|
|
private static function _assign_post_to_organization($post_id, $organization_id) {
|
|
if (class_exists('Groups_Post_Access')) {
|
|
$access_group_id = self::_get_organization_access_group_id($organization_id);
|
|
Groups_Post_Access::update( array( 'post_id' => $post_id, 'groups_read' => [$access_group_id] ) );
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Create corresponding access group for organization
|
|
*
|
|
* @param $organization_id
|
|
*/
|
|
private static function _create_organization_access_group($organization_id) {
|
|
if (class_exists('Groups_Group')) {
|
|
$organization = get_term_by('id', $organization_id, self::TAXONOMY_NAME);
|
|
$access_group_id = Groups_Group::create(array(
|
|
'name' => $organization->name,
|
|
));
|
|
|
|
add_term_meta($organization_id, 'group_id', $access_group_id);
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Remove corresponding access group for organization
|
|
*
|
|
* @param $organization_id
|
|
*/
|
|
private static function _remove_organization_access_group($organization_id) {
|
|
if (class_exists('Groups_Group')) {
|
|
$access_group_id = self::_get_organization_access_group_id($organization_id);
|
|
Groups_Group::delete($access_group_id);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add user to all access groups found in provided organization.
|
|
*
|
|
* @param $user_id
|
|
* @param $organization_id
|
|
*/
|
|
private static function _add_user_to_access_group($user_id, $organization_id) {
|
|
if (class_exists('Groups_User_Group')) {
|
|
$access_groups_ids = self::_get_organization_all_access_groups_ids($organization_id);
|
|
foreach ($access_groups_ids as $access_group_id) {
|
|
Groups_User_Group::create( array( 'user_id' => $user_id, 'group_id' => $access_group_id ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Remove user from all access groups found in provided organization,
|
|
*
|
|
* @param $user_id
|
|
* @param $organization_id
|
|
*/
|
|
private static function _remove_user_from_organization_access_groups($user_id, $organization_id) {
|
|
if (class_exists('Groups_User_Group')) {
|
|
$access_groups_ids = self::_get_organization_all_access_groups_ids($organization_id);
|
|
foreach ($access_groups_ids as $access_group_id) {
|
|
Groups_User_Group::delete($user_id, $access_group_id);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Show organizations selection on new user form
|
|
*/
|
|
function show_organizations_selection() {
|
|
$terms = get_terms( array(
|
|
'taxonomy' => self::TAXONOMY_NAME,
|
|
'hide_empty' => false,
|
|
) );
|
|
$taxonomy = get_taxonomy(self::TAXONOMY_NAME);
|
|
$this->table_contents(null, $taxonomy, $terms);
|
|
}
|
|
|
|
function edit_user_relationships($user = false) {
|
|
$tax = get_taxonomy( $this->taxonomy );
|
|
|
|
// Get the terms of the taxonomy.
|
|
$terms = get_terms( $this->taxonomy, array(
|
|
'hide_empty' => false
|
|
) );
|
|
|
|
$this->table_contents( $user, $tax, $terms );
|
|
}
|
|
|
|
function table_contents( $user, $tax, $terms ) {
|
|
$active_organization_id = -1;
|
|
if ($user) {
|
|
$active_organization = self::get_user_organization($user->ID);
|
|
$active_organization_id = $active_organization ? $active_organization->term_id : -1;
|
|
}
|
|
|
|
?>
|
|
<table class="form-table">
|
|
<tbody>
|
|
<tr class="form-field">
|
|
<th scope="row">
|
|
<label for="<?php echo esc_attr( $this->taxonomy ); ?>[]">
|
|
<?php echo esc_html( $tax->labels->singular_name ); ?>
|
|
</label>
|
|
</th>
|
|
<td>
|
|
<select name="<?php echo esc_attr( $this->taxonomy ); ?>[]" id="<?php echo esc_attr( $this->taxonomy ); ?>">
|
|
<?php
|
|
foreach ( $terms as $term ) :
|
|
$selected = $active_organization_id === $term->term_id;
|
|
?>
|
|
<option
|
|
value="<?php echo esc_attr( $term->slug ); ?>"
|
|
<?php selected( $selected ); ?>
|
|
>
|
|
<?php echo esc_attr( $term->name ); ?>
|
|
</option>
|
|
<?php
|
|
endforeach;
|
|
?>
|
|
</select>
|
|
<?php
|
|
wp_nonce_field( $this->taxonomy, $this->get_nonce_key() );
|
|
?>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<?php
|
|
}
|
|
|
|
private function get_nonce_key() {
|
|
return "wp_user_taxonomy_{$this->taxonomy}";
|
|
}
|
|
}
|