first commit
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace WPML\TM\User;
|
||||
|
||||
class Hooks implements \IWPML_Backend_Action {
|
||||
|
||||
public function add_hooks() {
|
||||
add_action( 'clean_user_cache', [ $this, 'cleanUserCacheAction' ] );
|
||||
add_action( 'updated_user_meta', [ $this, 'updatedUserMetaAction' ] );
|
||||
|
||||
add_filter( 'wpml_show_hidden_languages_options', [ $this, 'filter_show_hidden_languages_options' ] );
|
||||
}
|
||||
|
||||
public function cleanUserCacheAction() {
|
||||
$this->flushCache();
|
||||
}
|
||||
|
||||
public function updatedUserMetaAction() {
|
||||
$this->flushCache();
|
||||
}
|
||||
|
||||
public function filter_show_hidden_languages_options( $show_hidden_languages_options ) {
|
||||
if (
|
||||
current_user_can( \WPML_Manage_Translations_Role::CAPABILITY )
|
||||
|| current_user_can( \WPML_Translator_Role::CAPABILITY )
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $show_hidden_languages_options;
|
||||
}
|
||||
|
||||
private function flushCache() {
|
||||
wpml_get_cache( \WPML_Translation_Roles_Records::CACHE_GROUP )->flush_group_cache();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Only_I_Language_Pairs implements IWPML_AJAX_Action, IWPML_DIC_Action {
|
||||
|
||||
/** @var WPML_Language_Pair_Records $language_pair_records */
|
||||
private $language_pair_records;
|
||||
|
||||
public function __construct( WPML_Language_Pair_Records $language_pair_records ) {
|
||||
$this->language_pair_records = $language_pair_records;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_action( 'wpml_update_active_languages', array( $this, 'update_language_pairs' ) );
|
||||
}
|
||||
|
||||
public function update_language_pairs() {
|
||||
$users = get_users( [
|
||||
'meta_key' => WPML_TM_Wizard_Options::ONLY_I_USER_META,
|
||||
'meta_value' => true,
|
||||
] );
|
||||
|
||||
$all_language_pairs = WPML_All_Language_Pairs::get();
|
||||
|
||||
foreach ( $users as $user ) {
|
||||
$this->language_pair_records->store(
|
||||
$user->ID,
|
||||
$all_language_pairs
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
use WPML\FP\Relation;
|
||||
|
||||
class WPML_Translation_Manager_Records extends WPML_Translation_Roles_Records {
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function get_capability() {
|
||||
return WPML_Manage_Translations_Role::CAPABILITY;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function get_required_wp_roles() {
|
||||
|
||||
return wpml_collect( $this->wp_roles->role_objects )
|
||||
->filter( [ $this, 'is_required_role' ] )
|
||||
->keys()
|
||||
->reject( Relation::equals( 'administrator' ) ) // Admins always have Translation Manager caps.
|
||||
->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the role can be used for a manager.
|
||||
*
|
||||
* @param \WP_Role $role The role definition.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_required_role( WP_Role $role ) {
|
||||
return array_key_exists( 'edit_private_posts', $role->capabilities );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,257 @@
|
||||
<?php
|
||||
|
||||
abstract class WPML_Translation_Roles_Records {
|
||||
|
||||
const USERS_WITH_CAPABILITY = 'LIKE';
|
||||
const USERS_WITHOUT_CAPABILITY = 'NOT LIKE';
|
||||
const MIN_SEARCH_LENGTH = 3;
|
||||
const CACHE_GROUP = __CLASS__;
|
||||
|
||||
/** @var wpdb */
|
||||
protected $wpdb;
|
||||
|
||||
/** @var WPML_WP_User_Query_Factory */
|
||||
private $user_query_factory;
|
||||
|
||||
/** @var \WP_Roles */
|
||||
protected $wp_roles;
|
||||
|
||||
/**
|
||||
* WPML_Translation_Roles_Records constructor.
|
||||
*
|
||||
* @param \wpdb $wpdb
|
||||
* @param \WPML_WP_User_Query_Factory $user_query_factory
|
||||
* @param \WP_Roles $wp_roles
|
||||
*/
|
||||
public function __construct( wpdb $wpdb, WPML_WP_User_Query_Factory $user_query_factory, WP_Roles $wp_roles ) {
|
||||
$this->wpdb = $wpdb;
|
||||
$this->user_query_factory = $user_query_factory;
|
||||
$this->wp_roles = $wp_roles;
|
||||
}
|
||||
|
||||
public function has_users_with_capability() {
|
||||
$sql = "
|
||||
SELECT EXISTS(
|
||||
SELECT user_id
|
||||
FROM {$this->wpdb->usermeta}
|
||||
WHERE meta_key = '{$this->wpdb->prefix}capabilities' AND meta_value LIKE %s
|
||||
)
|
||||
";
|
||||
|
||||
$sql = $this->wpdb->prepare( $sql, '%' . $this->get_capability() . '%' );
|
||||
|
||||
return (bool) $this->wpdb->get_var( $sql );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_users_with_capability() {
|
||||
return $this->get_records( self::USERS_WITH_CAPABILITY );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function get_number_of_users_with_capability() {
|
||||
return count( $this->get_users_with_capability() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $search
|
||||
* @param int $limit
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function search_for_users_without_capability( $search = '', $limit = -1 ) {
|
||||
return $this->get_records( self::USERS_WITHOUT_CAPABILITY, $search, $limit );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $user_id
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function does_user_have_capability( $user_id ) {
|
||||
$users = $this->get_users_with_capability();
|
||||
foreach ( $users as $user ) {
|
||||
if ( (int) $user->ID === (int) $user_id ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete records for all users
|
||||
*/
|
||||
public function delete_all() {
|
||||
$users = $this->get_users_with_capability();
|
||||
foreach ( $users as $user ) {
|
||||
$this->delete( $user->ID );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the record for the user
|
||||
*
|
||||
* @param int $user_id
|
||||
*/
|
||||
public function delete( $user_id ) {
|
||||
$user = new WP_User( $user_id );
|
||||
$user->remove_cap( $this->get_capability() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $compare
|
||||
* @param string $search
|
||||
* @param int $limit
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_records( $compare, $search = '', $limit = -1 ) {
|
||||
$search = trim( $search );
|
||||
|
||||
$cache_key = md5( wp_json_encode( [ get_class( $this ), $compare, $search, $limit ] ) );
|
||||
$cache = wpml_get_cache( self::CACHE_GROUP );
|
||||
$found = false;
|
||||
$results = $cache->get( $cache_key, $found );
|
||||
if ( $found ) {
|
||||
return $results;
|
||||
}
|
||||
|
||||
$query_args = array(
|
||||
'fields' => 'ID',
|
||||
'meta_query' => array(
|
||||
array(
|
||||
'key' => "{$this->wpdb->prefix}capabilities",
|
||||
'value' => $this->get_capability(),
|
||||
'compare' => $compare,
|
||||
),
|
||||
),
|
||||
'number' => $limit,
|
||||
);
|
||||
|
||||
if ( 'NOT LIKE' === $compare ) {
|
||||
$required_wp_roles = $this->get_required_wp_roles();
|
||||
if ( $required_wp_roles ) {
|
||||
$query_args['role__in'] = $required_wp_roles;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $search ) {
|
||||
$query_args['search'] = '*' . $search . '*';
|
||||
$query_args['search_columns'] = array( 'user_login', 'user_nicename', 'user_email' );
|
||||
}
|
||||
|
||||
$user_query = $this->user_query_factory->create( $query_args );
|
||||
$users = $user_query->get_results();
|
||||
|
||||
if ( $search && strlen( $search ) > self::MIN_SEARCH_LENGTH && ( $limit <= 0 || count( $users ) < $limit ) ) {
|
||||
$users_from_metas = $this->get_records_from_users_metas( $compare, $search, $limit );
|
||||
$users_with_dupes = array_merge( $users, $users_from_metas );
|
||||
$users = wpml_array_unique( $users_with_dupes, SORT_REGULAR );
|
||||
}
|
||||
|
||||
$results = array();
|
||||
foreach ( $users as $user_id ) {
|
||||
$user_data = get_userdata( $user_id );
|
||||
if ( $user_data ) {
|
||||
$language_pair_records = new WPML_Language_Pair_Records( $this->wpdb, new WPML_Language_Records( $this->wpdb ) );
|
||||
$language_pairs = $language_pair_records->get( $user_id );
|
||||
|
||||
$result = (object) array(
|
||||
'ID' => $user_data->ID,
|
||||
'full_name' => trim( $user_data->first_name . ' ' . $user_data->last_name ),
|
||||
'user_login' => $user_data->user_login,
|
||||
'user_email' => $user_data->user_email,
|
||||
'display_name' => $user_data->display_name,
|
||||
'language_pairs' => $language_pairs,
|
||||
'roles' => $user_data->roles
|
||||
);
|
||||
$results[] = $result;
|
||||
}
|
||||
}
|
||||
|
||||
$cache->set( $cache_key, $results );
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $compare
|
||||
* @param string $search
|
||||
* @param int $limit
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_records_from_users_metas( $compare, $search, $limit = -1 ) {
|
||||
$search = trim( $search );
|
||||
if ( ! $search ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$sanitized_search = preg_replace( '!\s+!', ' ', $search );
|
||||
$words = explode( ' ', $sanitized_search );
|
||||
|
||||
if ( ! $words ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$search_by_names = array( 'relation' => 'OR' );
|
||||
|
||||
foreach ( $words as $word ) {
|
||||
$search_by_names[] = array(
|
||||
'key' => 'first_name',
|
||||
'value' => $word,
|
||||
'compare' => 'LIKE',
|
||||
);
|
||||
$search_by_names[] = array(
|
||||
'key' => 'last_name',
|
||||
'value' => $word,
|
||||
'compare' => 'LIKE',
|
||||
);
|
||||
$search_by_names[] = array(
|
||||
'key' => 'last_name',
|
||||
'value' => $word,
|
||||
'compare' => 'LIKE',
|
||||
);
|
||||
}
|
||||
|
||||
$query_args = array(
|
||||
'fields' => 'ID',
|
||||
'meta_query' => array(
|
||||
'relation' => 'AND',
|
||||
array(
|
||||
'key' => "{$this->wpdb->prefix}capabilities",
|
||||
'value' => $this->get_capability(),
|
||||
'compare' => $compare,
|
||||
),
|
||||
$search_by_names,
|
||||
),
|
||||
'number' => $limit,
|
||||
);
|
||||
|
||||
if ( 'NOT LIKE' === $compare ) {
|
||||
$required_wp_roles = $this->get_required_wp_roles();
|
||||
if ( $required_wp_roles ) {
|
||||
$query_args['role__in'] = $required_wp_roles;
|
||||
}
|
||||
}
|
||||
|
||||
$user_query = $this->user_query_factory->create( $query_args );
|
||||
|
||||
return $user_query->get_results();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function get_capability();
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
abstract protected function get_required_wp_roles();
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
class WPML_Translator_Admin_Records extends WPML_Translator_Records {
|
||||
|
||||
protected function get_required_wp_roles() {
|
||||
return array( 'administrator' );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
class WPML_Translator_Records extends WPML_Translation_Roles_Records {
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function get_capability() {
|
||||
return WPML_Translator_Role::CAPABILITY;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function get_required_wp_roles() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $source_language
|
||||
* @param array $target_languages
|
||||
* @param bool $require_all_languages - Translator must have all target languages if true otherwise they need at least one.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_users_with_languages( $source_language, $target_languages, $require_all_languages = true ) {
|
||||
$translators = $this->get_users_with_capability();
|
||||
|
||||
$language_records = new WPML_Language_Records( $this->wpdb );
|
||||
$language_pairs_records = new WPML_Language_Pair_Records( $this->wpdb, $language_records );
|
||||
|
||||
$translators_with_langs = array();
|
||||
foreach ( $translators as $translator ) {
|
||||
$language_pairs_for_user = $language_pairs_records->get( $translator->ID );
|
||||
|
||||
if ( isset( $language_pairs_for_user[ $source_language ] ) ) {
|
||||
$lang_count = 0;
|
||||
foreach ( $target_languages as $target_language ) {
|
||||
$lang_count += in_array( $target_language, $language_pairs_for_user[ $source_language ], true ) ? 1 : 0;
|
||||
}
|
||||
if (
|
||||
$require_all_languages && $lang_count === count( $target_languages ) ||
|
||||
! $require_all_languages && $lang_count > 0
|
||||
) {
|
||||
$translators_with_langs[] = $translator;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $translators_with_langs;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
class WPML_User_Jobs_Notification_Settings_Render {
|
||||
|
||||
private $section_template;
|
||||
|
||||
/**
|
||||
* WPML_User_Jobs_Notification_Settings_Render constructor.
|
||||
*
|
||||
* @param WPML_User_Jobs_Notification_Settings_Template|null $notification_settings_template
|
||||
*/
|
||||
public function __construct( WPML_User_Jobs_Notification_Settings_Template $notification_settings_template ) {
|
||||
$this->section_template = $notification_settings_template;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_action( 'wpml_user_profile_options', array( $this, 'render_options' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $user_id
|
||||
*/
|
||||
public function render_options( $user_id ) {
|
||||
$field_checked = checked( true, WPML_User_Jobs_Notification_Settings::is_new_job_notification_enabled( $user_id ), false );
|
||||
echo $this->get_notification_template()->get_setting_section( $field_checked );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|WPML_User_Jobs_Notification_Settings_Template
|
||||
*/
|
||||
private function get_notification_template() {
|
||||
return $this->section_template;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_User_Jobs_Notification_Settings_Template
|
||||
*/
|
||||
class WPML_User_Jobs_Notification_Settings_Template {
|
||||
|
||||
const TEMPLATE_FILE = 'job-email-notification.twig';
|
||||
|
||||
/**
|
||||
* @var WPML_Twig_Template
|
||||
*/
|
||||
private $template_service;
|
||||
|
||||
/**
|
||||
* WPML_User_Jobs_Notification_Settings_Template constructor.
|
||||
*
|
||||
* @param IWPML_Template_Service $template_service
|
||||
*/
|
||||
public function __construct( IWPML_Template_Service $template_service ) {
|
||||
$this->template_service = $template_service;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $notification_input
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_setting_section( $notification_input ) {
|
||||
$model = $this->get_model( $notification_input );
|
||||
|
||||
return $this->template_service->show( $model, self::TEMPLATE_FILE );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $notification_input
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_model( $notification_input ) {
|
||||
$model = array(
|
||||
'strings' => array(
|
||||
'section_title' => __( 'WPML Translator Settings', 'wpml-translation-management' ),
|
||||
'field_title' => __( 'Notification emails:', 'wpml-translation-management' ),
|
||||
'field_name' => WPML_User_Jobs_Notification_Settings::BLOCK_NEW_NOTIFICATION_FIELD,
|
||||
'field_text' => __( 'Send me a notification email when there is something new to translate', 'wpml-translation-management' ),
|
||||
'checked' => $notification_input,
|
||||
),
|
||||
);
|
||||
|
||||
return $model;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_Jobs_Notification_Settings
|
||||
*/
|
||||
class WPML_User_Jobs_Notification_Settings {
|
||||
|
||||
const BLOCK_NEW_NOTIFICATION_FIELD = 'wpml_block_new_email_notifications';
|
||||
|
||||
public function add_hooks() {
|
||||
add_action( 'personal_options_update', array( $this, 'save_new_job_notifications_setting' ) );
|
||||
add_action( 'edit_user_profile_update', array( $this, 'save_new_job_notifications_setting' ) );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $user_id
|
||||
*/
|
||||
public function save_new_job_notifications_setting( $user_id ) {
|
||||
$val = 1;
|
||||
if ( array_key_exists( self::BLOCK_NEW_NOTIFICATION_FIELD, $_POST ) ) {
|
||||
$val = filter_var( $_POST[ self::BLOCK_NEW_NOTIFICATION_FIELD ], FILTER_SANITIZE_NUMBER_INT );
|
||||
}
|
||||
update_user_meta( $user_id, self::BLOCK_NEW_NOTIFICATION_FIELD, $val );
|
||||
}
|
||||
|
||||
public static function is_new_job_notification_enabled( $user_id ) {
|
||||
return ! get_user_meta( $user_id, self::BLOCK_NEW_NOTIFICATION_FIELD, true );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user