Keep profile photos and fields in line with Microsoft 365 on every run
Some checks are pending
CI / PHP lint (7.4) (pull_request) Waiting to run
CI / PHP lint (8.0) (pull_request) Waiting to run
CI / PHP lint (8.1) (pull_request) Waiting to run
CI / PHP lint (8.2) (pull_request) Waiting to run
CI / PHP lint (8.3) (pull_request) Waiting to run
CI / PHP lint (8.4) (pull_request) Waiting to run
CI / WordPress Coding Standards (pull_request) Waiting to run
CI / WordPress.org Plugin Check (pull_request) Waiting to run
Some checks are pending
CI / PHP lint (7.4) (pull_request) Waiting to run
CI / PHP lint (8.0) (pull_request) Waiting to run
CI / PHP lint (8.1) (pull_request) Waiting to run
CI / PHP lint (8.2) (pull_request) Waiting to run
CI / PHP lint (8.3) (pull_request) Waiting to run
CI / PHP lint (8.4) (pull_request) Waiting to run
CI / WordPress Coding Standards (pull_request) Waiting to run
CI / WordPress.org Plugin Check (pull_request) Waiting to run
- Photo versions are compared on every sync run via Graph $batch (20 users per request); only changed photos are downloaded, the old file is deleted and the avatar URL changes. Photos deleted in Microsoft 365 are deleted in WordPress. Graph errors never delete a photo. Download limit per run (500) with deferral to the next run. - Switching the photo sync off removes all stored photos; deselected m365_* profile fields are removed from the profiles. - A user's photo is deleted together with the user (delete_user hook). - Dry run reports photo changes without downloading. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
4edf20bc45
commit
9f77e9027f
11 changed files with 589 additions and 339 deletions
|
|
@ -10,6 +10,8 @@ All notable changes to this project are documented in this file. The format foll
|
||||||
- User sync (new "User sync" tab): imports Microsoft 365 / Entra ID users as WordPress accounts – the whole tenant or the (nested) members of selected groups, guests optional – and links existing accounts by e-mail address.
|
- User sync (new "User sync" tab): imports Microsoft 365 / Entra ID users as WordPress accounts – the whole tenant or the (nested) members of selected groups, guests optional – and links existing accounts by e-mail address.
|
||||||
- Default role plus group → role mapping with a Graph-powered group picker; mapped roles either added to or replacing the default role (first match wins, reorderable). Roles of accounts that existed before the sync are only managed on request.
|
- Default role plus group → role mapping with a Graph-powered group picker; mapped roles either added to or replacing the default role (first match wins, reorderable). Roles of accounts that existed before the sync are only managed on request.
|
||||||
- Selectable profile attributes (display name, first/last name, job title, department, company, office, employee ID, phones, address, language) and the profile photo, which replaces the Gravatar.
|
- Selectable profile attributes (display name, first/last name, job title, department, company, office, employee ID, phones, address, language) and the profile photo, which replaces the Gravatar.
|
||||||
|
- Profile photos follow Microsoft 365 on every run: versions are compared via Graph `$batch` (20 users per request), changed photos are downloaded again (old file deleted, new URL), photos deleted in Microsoft 365 are deleted in WordPress. Errors never delete a photo.
|
||||||
|
- Deselected profile fields (`m365_*`) and photos are removed from the profiles on the next run; fields cleared in Microsoft 365 are cleared in WordPress; a user's photo is deleted together with the user.
|
||||||
- Deactivation or deletion of WordPress accounts whose Microsoft 365 account was disabled, deleted or removed from the sync groups; automatic reactivation. Deactivated accounts cannot sign in at all (Microsoft, password, application passwords) and lose all sessions.
|
- Deactivation or deletion of WordPress accounts whose Microsoft 365 account was disabled, deleted or removed from the sync groups; automatic reactivation. Deactivated accounts cannot sign in at all (Microsoft, password, application passwords) and lose all sessions.
|
||||||
- Safeguards: dry run, safety stop above 20 % deprovisioning (at least 5 accounts), abort on any Graph error, deletion only on a 404 for the object ID, protected pre-existing administrators and own account, content reassignment required for deletion, run lock.
|
- Safeguards: dry run, safety stop above 20 % deprovisioning (at least 5 accounts), abort on any Graph error, deletion only on a 404 for the object ID, protected pre-existing administrators and own account, content reassignment required for deletion, run lock.
|
||||||
- Scheduled sync via WP-Cron (hourly, twice daily, daily), `wp m365-login sync [--dry-run]`, report of the last run in the settings.
|
- Scheduled sync via WP-Cron (hourly, twice daily, daily), `wp m365-login sync [--dry-run]`, report of the last run in the settings.
|
||||||
|
|
|
||||||
17
README.md
17
README.md
|
|
@ -319,7 +319,22 @@ vollständig – manuelle Änderungen werden überschrieben.
|
||||||
Telefon (geschäftlich/mobil), Adresse, Sprache. Namen landen in den normalen WordPress-Feldern, alles andere in User-Meta mit
|
Telefon (geschäftlich/mobil), Adresse, Sprache. Namen landen in den normalen WordPress-Feldern, alles andere in User-Meta mit
|
||||||
dem Präfix `m365_` (z. B. `m365_department`) und wird auf der Profilseite angezeigt. Das **Profilbild** wird nach
|
dem Präfix `m365_` (z. B. `m365_department`) und wird auf der Profilseite angezeigt. Das **Profilbild** wird nach
|
||||||
`wp-content/uploads/m365-login-avatars/` geladen (Dateiname mit gesalzenem Hash statt Objekt-ID) und ersetzt überall den
|
`wp-content/uploads/m365-login-avatars/` geladen (Dateiname mit gesalzenem Hash statt Objekt-ID) und ersetzt überall den
|
||||||
Gravatar; es wird etwa einmal täglich pro Benutzer geprüft. Achtung: Avatare sind öffentlich sichtbar, wo WordPress sie anzeigt.
|
Gravatar. Achtung: Avatare sind öffentlich sichtbar, wo WordPress sie anzeigt.
|
||||||
|
|
||||||
|
Microsoft 365 hat immer Vorrang, bei jedem Lauf:
|
||||||
|
|
||||||
|
| In Microsoft 365 … | … in WordPress |
|
||||||
|
| --- | --- |
|
||||||
|
| Feld geändert | Feld wird überschrieben. |
|
||||||
|
| Feld geleert | Feld wird geleert (`m365_*`-Meta gelöscht; ein leerer Anzeigename wird nicht übernommen). |
|
||||||
|
| Profilbild geändert | Neues Bild wird geladen, das alte gelöscht; die Avatar-URL ändert sich, damit Browser nicht das alte Bild zeigen. |
|
||||||
|
| Profilbild gelöscht | Bild wird gelöscht, der Avatar fällt auf Gravatar zurück. |
|
||||||
|
|
||||||
|
Die Bildversionen werden per Graph-`$batch` geprüft (20 Benutzer pro Anfrage); heruntergeladen werden nur geänderte Bilder,
|
||||||
|
höchstens 500 pro Lauf, der Rest folgt im nächsten (Filter `m365_login_sync_photo_limit`, Prüfintervall per
|
||||||
|
`m365_login_sync_photo_interval`). Bei einem Fehler von Microsoft bleibt das vorhandene Bild erhalten – gelöscht wird nur,
|
||||||
|
wenn Microsoft ausdrücklich „kein Foto“ meldet. **Abgewählte** Felder und Bilder werden beim nächsten Lauf aus den Profilen
|
||||||
|
entfernt (Vor-, Nach- und Anzeigename bleiben stehen); wird ein Benutzer in WordPress gelöscht, wird auch sein Bild gelöscht.
|
||||||
|
|
||||||
**Deaktivierte Konten** können sich überhaupt nicht mehr anmelden – weder per Microsoft noch per Passwort,
|
**Deaktivierte Konten** können sich überhaupt nicht mehr anmelden – weder per Microsoft noch per Passwort,
|
||||||
Anwendungspasswort oder bestehender Session (alle Sessions werden beendet). In der Benutzerliste zeigt die Spalte
|
Anwendungspasswort oder bestehender Session (alle Sessions werden beendet). In der Benutzerliste zeigt die Spalte
|
||||||
|
|
|
||||||
|
|
@ -640,7 +640,7 @@ class M365_Login_Admin {
|
||||||
</label>
|
</label>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</div>
|
</div>
|
||||||
<p class="description"><?php esc_html_e( 'Profile photos are stored in wp-content/uploads/m365-login-avatars/ and replace the Gravatar. They are checked about once a day per user.', 'm365-login' ); ?></p>
|
<p class="description"><?php esc_html_e( 'Profile photos are stored in wp-content/uploads/m365-login-avatars/ and replace the Gravatar. They are compared on every run: changed photos are downloaded again, photos deleted in Microsoft 365 are deleted in WordPress too. Fields and photos you deselect here are removed from the profiles on the next run (first and last name and display name stay).', 'm365-login' ); ?></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="m365-card">
|
<div class="m365-card">
|
||||||
|
|
|
||||||
|
|
@ -277,52 +277,111 @@ class M365_Login_Graph {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Metadata of a user's profile photo (prefers the 240×240 rendition).
|
* Runs up to 20 GET requests in one Graph JSON batch.
|
||||||
|
*
|
||||||
|
* @param string[] $paths Request key => path relative to the v1.0 base.
|
||||||
|
* @return array|WP_Error Request key => array( 'status' => int, 'body' => mixed ).
|
||||||
|
*/
|
||||||
|
public function batch_get( $paths ) {
|
||||||
|
$requests = array();
|
||||||
|
foreach ( array_values( $paths ) as $i => $path ) {
|
||||||
|
$requests[] = array(
|
||||||
|
'id' => (string) $i,
|
||||||
|
'method' => 'GET',
|
||||||
|
'url' => $path,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$keys = array_keys( $paths );
|
||||||
|
if ( empty( $requests ) ) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
if ( count( $requests ) > 20 ) {
|
||||||
|
return new WP_Error( 'graph_batch_size', 'A Graph batch holds at most 20 requests.' );
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $this->request( 'POST', '/$batch', array( 'requests' => $requests ) );
|
||||||
|
if ( is_wp_error( $result ) ) {
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
$out = array();
|
||||||
|
foreach ( isset( $result['responses'] ) && is_array( $result['responses'] ) ? $result['responses'] : array() as $response ) {
|
||||||
|
$i = isset( $response['id'] ) ? (int) $response['id'] : -1;
|
||||||
|
if ( isset( $keys[ $i ] ) ) {
|
||||||
|
$out[ $keys[ $i ] ] = array(
|
||||||
|
'status' => isset( $response['status'] ) ? (int) $response['status'] : 0,
|
||||||
|
'body' => isset( $response['body'] ) ? $response['body'] : null,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Profile photo versions of several users (one batch request per 20 users).
|
||||||
|
*
|
||||||
|
* @param string[] $oids User object IDs.
|
||||||
|
* @return array oid => etag string, null (user has no photo) or WP_Error (could not be checked).
|
||||||
|
*/
|
||||||
|
public function photo_versions( $oids ) {
|
||||||
|
$out = array();
|
||||||
|
foreach ( array_chunk( array_values( array_filter( $oids, array( 'M365_Login_Settings', 'is_guid' ) ) ), 20 ) as $chunk ) {
|
||||||
|
$paths = array();
|
||||||
|
foreach ( $chunk as $oid ) {
|
||||||
|
$paths[ $oid ] = '/users/' . rawurlencode( strtolower( $oid ) ) . '/photo';
|
||||||
|
}
|
||||||
|
$responses = $this->batch_get( $paths );
|
||||||
|
foreach ( $chunk as $oid ) {
|
||||||
|
if ( is_wp_error( $responses ) ) {
|
||||||
|
$out[ $oid ] = $responses;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$response = isset( $responses[ $oid ] ) ? $responses[ $oid ] : array(
|
||||||
|
'status' => 0,
|
||||||
|
'body' => null,
|
||||||
|
);
|
||||||
|
if ( 404 === $response['status'] ) {
|
||||||
|
$out[ $oid ] = null;
|
||||||
|
} elseif ( 200 === $response['status'] && is_array( $response['body'] ) ) {
|
||||||
|
$etag = isset( $response['body']['@odata.mediaEtag'] ) ? (string) $response['body']['@odata.mediaEtag'] : '';
|
||||||
|
$out[ $oid ] = '' !== $etag ? $etag : md5( (string) wp_json_encode( $response['body'] ) );
|
||||||
|
} else {
|
||||||
|
$code = isset( $response['body']['error']['code'] ) ? (string) $response['body']['error']['code'] : 'HTTP ' . $response['status'];
|
||||||
|
$out[ $oid ] = new WP_Error( 'graph_photo', $code, array( 'status' => $response['status'] ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Downloads a user's photo (240×240 rendition, else the original).
|
||||||
*
|
*
|
||||||
* @param string $oid User object ID.
|
* @param string $oid User object ID.
|
||||||
* @return array|null|WP_Error array( 'path' => photo path, 'etag' => string ), null when the user has no photo.
|
* @return string|null|WP_Error Binary image data, null when the user has no photo.
|
||||||
*/
|
*/
|
||||||
public function photo_info( $oid ) {
|
public function photo_bytes( $oid ) {
|
||||||
if ( ! M365_Login_Settings::is_guid( $oid ) ) {
|
if ( ! M365_Login_Settings::is_guid( $oid ) ) {
|
||||||
return new WP_Error( 'graph_bad_oid', 'Invalid user object ID.' );
|
return new WP_Error( 'graph_bad_oid', 'Invalid user object ID.' );
|
||||||
}
|
}
|
||||||
$base = '/users/' . rawurlencode( strtolower( $oid ) );
|
$base = '/users/' . rawurlencode( strtolower( $oid ) );
|
||||||
foreach ( array( $base . '/photos/240x240', $base . '/photo' ) as $path ) {
|
foreach ( array( $base . '/photos/240x240/$value', $base . '/photo/$value' ) as $path ) {
|
||||||
$meta = $this->request( 'GET', $path );
|
$response = $this->raw_request( 'GET', $path, null, array( 'Accept' => 'image/*' ) );
|
||||||
if ( is_wp_error( $meta ) ) {
|
if ( is_wp_error( $response ) ) {
|
||||||
if ( self::is_not_found( $meta ) ) {
|
return $response;
|
||||||
continue;
|
}
|
||||||
}
|
$code = (int) wp_remote_retrieve_response_code( $response );
|
||||||
return $meta;
|
$body = wp_remote_retrieve_body( $response );
|
||||||
|
if ( 200 === $code ) {
|
||||||
|
return $body;
|
||||||
|
}
|
||||||
|
if ( 404 !== $code ) {
|
||||||
|
return $this->error_from( $code, json_decode( $body, true ) );
|
||||||
}
|
}
|
||||||
$etag = isset( $meta['@odata.mediaEtag'] ) ? (string) $meta['@odata.mediaEtag'] : '';
|
|
||||||
return array(
|
|
||||||
'path' => $path,
|
|
||||||
'etag' => '' !== $etag ? $etag : md5( (string) wp_json_encode( $meta ) ),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Downloads photo bytes.
|
|
||||||
*
|
|
||||||
* @param string $path Photo path returned by photo_info().
|
|
||||||
* @return string|WP_Error Binary image data.
|
|
||||||
*/
|
|
||||||
public function photo_bytes( $path ) {
|
|
||||||
$response = $this->raw_request( 'GET', $path . '/$value', null, array( 'Accept' => 'image/*' ) );
|
|
||||||
if ( is_wp_error( $response ) ) {
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
$code = (int) wp_remote_retrieve_response_code( $response );
|
|
||||||
$body = wp_remote_retrieve_body( $response );
|
|
||||||
if ( 200 !== $code ) {
|
|
||||||
return $this->error_from( $code, json_decode( $body, true ) );
|
|
||||||
}
|
|
||||||
return $body;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Searches groups by display name.
|
* Searches groups by display name.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,7 @@ class M365_Login_Sync {
|
||||||
add_filter( 'determine_current_user', array( $this, 'drop_disabled_session' ), 100 );
|
add_filter( 'determine_current_user', array( $this, 'drop_disabled_session' ), 100 );
|
||||||
|
|
||||||
add_filter( 'pre_get_avatar_data', array( $this, 'avatar_data' ), 10, 2 );
|
add_filter( 'pre_get_avatar_data', array( $this, 'avatar_data' ), 10, 2 );
|
||||||
|
add_action( 'delete_user', array( $this, 'delete_photo' ) );
|
||||||
|
|
||||||
if ( is_admin() ) {
|
if ( is_admin() ) {
|
||||||
add_filter( 'manage_users_columns', array( $this, 'users_column' ) );
|
add_filter( 'manage_users_columns', array( $this, 'users_column' ) );
|
||||||
|
|
@ -394,7 +395,7 @@ class M365_Login_Sync {
|
||||||
$linked = $this->linked_users();
|
$linked = $this->linked_users();
|
||||||
$seen = array();
|
$seen = array();
|
||||||
$pending = array(); // Deactivations/deletions, applied after the safety check.
|
$pending = array(); // Deactivations/deletions, applied after the safety check.
|
||||||
$photos = 0;
|
$photo_of = array(); // oid => WP_User whose photo is kept in sync.
|
||||||
$photo_on = array_key_exists( 'photo', $this->selected_attributes() );
|
$photo_on = array_key_exists( 'photo', $this->selected_attributes() );
|
||||||
|
|
||||||
foreach ( $people as $person ) {
|
foreach ( $people as $person ) {
|
||||||
|
|
@ -404,11 +405,18 @@ class M365_Login_Sync {
|
||||||
$result = $this->sync_person( $person, $linked, $memberships );
|
$result = $this->sync_person( $person, $linked, $memberships );
|
||||||
if ( is_array( $result ) ) {
|
if ( is_array( $result ) ) {
|
||||||
$pending[] = $result;
|
$pending[] = $result;
|
||||||
} elseif ( $result instanceof WP_User && $photo_on && ! $this->dry ) {
|
} elseif ( $result instanceof WP_User ) {
|
||||||
$photos += $this->maybe_sync_photo( $result, $oid, $photos );
|
$photo_of[ $oid ] = $result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Profile photos: new, changed and removed photos, or cleanup when the photo sync was switched off.
|
||||||
|
if ( $photo_on ) {
|
||||||
|
$this->sync_photos( $photo_of );
|
||||||
|
} else {
|
||||||
|
$this->remove_all_photos();
|
||||||
|
}
|
||||||
|
|
||||||
// 3. Linked accounts that were not part of the directory listing.
|
// 3. Linked accounts that were not part of the directory listing.
|
||||||
foreach ( $linked as $oid => $user_id ) {
|
foreach ( $linked as $oid => $user_id ) {
|
||||||
if ( isset( $seen[ $oid ] ) ) {
|
if ( isset( $seen[ $oid ] ) ) {
|
||||||
|
|
@ -776,6 +784,22 @@ class M365_Login_Sync {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fields that are no longer selected are removed from the profile (only the plugin's own m365_* keys).
|
||||||
|
$selected = $this->selected_attributes();
|
||||||
|
foreach ( $labels as $key => $attribute ) {
|
||||||
|
$target = isset( $attribute['target'] ) ? (string) $attribute['target'] : '';
|
||||||
|
if ( isset( $selected[ $key ] ) || 0 !== strpos( $target, 'm365_' ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( '' !== (string) get_user_meta( $user->ID, $target, true ) ) {
|
||||||
|
if ( ! $this->dry ) {
|
||||||
|
delete_user_meta( $user->ID, $target );
|
||||||
|
}
|
||||||
|
/* translators: %s: profile field */
|
||||||
|
$changes[] = sprintf( __( '%s removed', 'm365-login' ), $attribute['label'] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( $fields && ! $this->dry ) {
|
if ( $fields && ! $this->dry ) {
|
||||||
$fields['ID'] = $user->ID;
|
$fields['ID'] = $user->ID;
|
||||||
$result = wp_update_user( $fields );
|
$result = wp_update_user( $fields );
|
||||||
|
|
@ -996,8 +1020,7 @@ class M365_Login_Sync {
|
||||||
$this->log( 'info', sprintf( __( '%1$s: account deleted (%2$s).', 'm365-login' ), $user->user_email, $action['label'] ) );
|
$this->log( 'info', sprintf( __( '%1$s: account deleted (%2$s).', 'm365-login' ), $user->user_email, $action['label'] ) );
|
||||||
$this->count( 'deleted' );
|
$this->count( 'deleted' );
|
||||||
if ( ! $this->dry ) {
|
if ( ! $this->dry ) {
|
||||||
$this->delete_photo( $user->ID );
|
wp_delete_user( $user->ID, $reassign ); // The delete_user hook removes the photo.
|
||||||
wp_delete_user( $user->ID, $reassign );
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1133,89 +1156,182 @@ class M365_Login_Sync {
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Refreshes the profile photo when it was not checked recently.
|
* Brings the stored photos in line with Microsoft 365: downloads new and changed
|
||||||
|
* photos and deletes photos that were removed in Microsoft 365.
|
||||||
*
|
*
|
||||||
* @param WP_User $user User.
|
* Photo versions are compared on every run (20 users per Graph batch request);
|
||||||
* @param string $oid Object ID.
|
* only changed photos are downloaded.
|
||||||
* @param int $done_so_far Photo checks done in this run.
|
*
|
||||||
* @return int 1 when Graph was asked, 0 otherwise.
|
* @param WP_User[] $users oid => user.
|
||||||
*/
|
*/
|
||||||
private function maybe_sync_photo( $user, $oid, $done_so_far ) {
|
private function sync_photos( $users ) {
|
||||||
/**
|
/**
|
||||||
* Maximum number of profile photo checks per sync run (the rest follows in later runs).
|
* Minimum number of seconds between two photo checks of the same user (0 = every run).
|
||||||
*
|
|
||||||
* @param int $limit Limit.
|
|
||||||
*/
|
|
||||||
if ( $done_so_far >= (int) apply_filters( 'm365_login_sync_photo_limit', 200 ) ) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
$stored = get_user_meta( $user->ID, self::META_PHOTO, true );
|
|
||||||
$stored = is_array( $stored ) ? $stored : array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Seconds between two photo checks of the same user.
|
|
||||||
*
|
*
|
||||||
* @param int $interval Interval.
|
* @param int $interval Interval.
|
||||||
*/
|
*/
|
||||||
$interval = (int) apply_filters( 'm365_login_sync_photo_interval', 20 * HOUR_IN_SECONDS );
|
$interval = (int) apply_filters( 'm365_login_sync_photo_interval', 0 );
|
||||||
if ( ! empty( $stored['checked'] ) && time() - (int) $stored['checked'] < $interval ) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
$info = $this->graph->photo_info( $oid );
|
/**
|
||||||
if ( is_wp_error( $info ) ) {
|
* Maximum number of photo downloads per sync run (the rest follows in later runs).
|
||||||
/* translators: 1: e-mail address, 2: error message */
|
*
|
||||||
$this->log( 'warning', sprintf( __( '%1$s: profile photo could not be read: %2$s', 'm365-login' ), $user->user_email, $info->get_error_message() ) );
|
* @param int $limit Limit.
|
||||||
return 1;
|
*/
|
||||||
}
|
$limit = (int) apply_filters( 'm365_login_sync_photo_limit', 500 );
|
||||||
|
|
||||||
if ( null === $info ) {
|
$check = array();
|
||||||
if ( ! empty( $stored['file'] ) ) {
|
foreach ( $users as $oid => $user ) {
|
||||||
$this->delete_photo( $user->ID );
|
$stored = $this->stored_photo( $user->ID );
|
||||||
/* translators: %s: e-mail address */
|
if ( $interval > 0 && ! empty( $stored['checked'] ) && time() - (int) $stored['checked'] < $interval ) {
|
||||||
$this->log( 'info', sprintf( __( '%s: profile photo removed.', 'm365-login' ), $user->user_email ) );
|
continue;
|
||||||
$this->count( 'photos' );
|
|
||||||
}
|
}
|
||||||
|
$check[ $oid ] = $user;
|
||||||
|
}
|
||||||
|
if ( empty( $check ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$versions = $this->graph->photo_versions( array_keys( $check ) );
|
||||||
|
$downloads = 0;
|
||||||
|
$deferred = 0;
|
||||||
|
|
||||||
|
foreach ( $check as $oid => $user ) {
|
||||||
|
$version = array_key_exists( $oid, $versions ) ? $versions[ $oid ] : new WP_Error( 'graph_photo', 'No answer.' );
|
||||||
|
$stored = $this->stored_photo( $user->ID );
|
||||||
|
|
||||||
|
// Never delete anything because of an error – only a clear "no photo" removes it.
|
||||||
|
if ( is_wp_error( $version ) ) {
|
||||||
|
/* translators: 1: e-mail address, 2: error message */
|
||||||
|
$this->log( 'warning', sprintf( __( '%1$s: profile photo could not be read: %2$s', 'm365-login' ), $user->user_email, $version->get_error_message() ) );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( null === $version ) {
|
||||||
|
if ( ! empty( $stored['file'] ) ) {
|
||||||
|
$this->remove_photo( $user );
|
||||||
|
} elseif ( ! $this->dry ) {
|
||||||
|
update_user_meta( $user->ID, self::META_PHOTO, array( 'checked' => time() ) );
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! empty( $stored['file'] ) && isset( $stored['etag'] ) && $stored['etag'] === $version && file_exists( self::photo_path( $stored['file'] ) ) ) {
|
||||||
|
if ( ! $this->dry ) {
|
||||||
|
$stored['checked'] = time();
|
||||||
|
update_user_meta( $user->ID, self::META_PHOTO, $stored );
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// New or changed photo.
|
||||||
|
if ( $this->dry ) {
|
||||||
|
/* translators: %s: e-mail address */
|
||||||
|
$this->log( 'info', sprintf( __( '%s: profile photo updated.', 'm365-login' ), $user->user_email ) );
|
||||||
|
$this->count( 'photos' );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( $downloads >= $limit ) {
|
||||||
|
++$deferred;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
++$downloads;
|
||||||
|
|
||||||
|
$bytes = $this->graph->photo_bytes( $oid );
|
||||||
|
if ( null === $bytes ) {
|
||||||
|
if ( ! empty( $stored['file'] ) ) {
|
||||||
|
$this->remove_photo( $user );
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ( is_wp_error( $bytes ) || '' === $bytes || strlen( $bytes ) > self::PHOTO_MAX ) {
|
||||||
|
/* translators: %s: e-mail address */
|
||||||
|
$this->log( 'warning', sprintf( __( '%s: profile photo could not be downloaded.', 'm365-login' ), $user->user_email ) );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$file = $this->store_photo( $user->ID, $oid, $version, $bytes );
|
||||||
|
if ( '' === $file ) {
|
||||||
|
/* translators: %s: e-mail address */
|
||||||
|
$this->log( 'warning', sprintf( __( '%s: profile photo is not a valid image or could not be saved.', 'm365-login' ), $user->user_email ) );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! empty( $stored['file'] ) && $stored['file'] !== $file ) {
|
||||||
|
wp_delete_file( self::photo_path( $stored['file'] ) );
|
||||||
|
}
|
||||||
|
update_user_meta(
|
||||||
|
$user->ID,
|
||||||
|
self::META_PHOTO,
|
||||||
|
array(
|
||||||
|
'file' => $file,
|
||||||
|
'etag' => $version,
|
||||||
|
'checked' => time(),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
/* translators: %s: e-mail address */
|
||||||
|
$this->log( 'info', sprintf( __( '%s: profile photo updated.', 'm365-login' ), $user->user_email ) );
|
||||||
|
$this->count( 'photos' );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $deferred ) {
|
||||||
|
/* translators: %d: number of photos */
|
||||||
|
$this->log( 'info', sprintf( _n( '%d changed profile photo will be downloaded in the next run (download limit per run reached).', '%d changed profile photos will be downloaded in the next run (download limit per run reached).', $deferred, 'm365-login' ), $deferred ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the stored photo of a user whose photo was deleted in Microsoft 365.
|
||||||
|
*
|
||||||
|
* @param WP_User $user User.
|
||||||
|
*/
|
||||||
|
private function remove_photo( $user ) {
|
||||||
|
if ( ! $this->dry ) {
|
||||||
|
$this->delete_photo( $user->ID );
|
||||||
update_user_meta( $user->ID, self::META_PHOTO, array( 'checked' => time() ) );
|
update_user_meta( $user->ID, self::META_PHOTO, array( 'checked' => time() ) );
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
/* translators: %s: e-mail address */
|
||||||
|
$this->log( 'info', sprintf( __( '%s: profile photo removed.', 'm365-login' ), $user->user_email ) );
|
||||||
|
$this->count( 'photos' );
|
||||||
|
}
|
||||||
|
|
||||||
if ( ! empty( $stored['file'] ) && isset( $stored['etag'] ) && $stored['etag'] === $info['etag'] && file_exists( self::photo_path( $stored['file'] ) ) ) {
|
/**
|
||||||
$stored['checked'] = time();
|
* Deletes every stored photo (the photo sync was switched off).
|
||||||
update_user_meta( $user->ID, self::META_PHOTO, $stored );
|
*/
|
||||||
return 1;
|
private function remove_all_photos() {
|
||||||
}
|
$users = get_users(
|
||||||
|
|
||||||
$bytes = $this->graph->photo_bytes( $info['path'] );
|
|
||||||
if ( is_wp_error( $bytes ) || '' === $bytes || strlen( $bytes ) > self::PHOTO_MAX ) {
|
|
||||||
/* translators: %s: e-mail address */
|
|
||||||
$this->log( 'warning', sprintf( __( '%s: profile photo could not be downloaded.', 'm365-login' ), $user->user_email ) );
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
$file = $this->store_photo( $user->ID, $oid, $info['etag'], $bytes );
|
|
||||||
if ( '' === $file ) {
|
|
||||||
/* translators: %s: e-mail address */
|
|
||||||
$this->log( 'warning', sprintf( __( '%s: profile photo is not a valid image or could not be saved.', 'm365-login' ), $user->user_email ) );
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! empty( $stored['file'] ) && $stored['file'] !== $file ) {
|
|
||||||
wp_delete_file( self::photo_path( $stored['file'] ) );
|
|
||||||
}
|
|
||||||
update_user_meta(
|
|
||||||
$user->ID,
|
|
||||||
self::META_PHOTO,
|
|
||||||
array(
|
array(
|
||||||
'file' => $file,
|
'meta_key' => self::META_PHOTO, // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
|
||||||
'etag' => $info['etag'],
|
'meta_compare' => 'EXISTS',
|
||||||
'checked' => time(),
|
'fields' => array( 'ID' ),
|
||||||
|
'number' => -1,
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
/* translators: %s: e-mail address */
|
$removed = 0;
|
||||||
$this->log( 'info', sprintf( __( '%s: profile photo updated.', 'm365-login' ), $user->user_email ) );
|
foreach ( $users as $row ) {
|
||||||
$this->count( 'photos' );
|
$stored = $this->stored_photo( (int) $row->ID );
|
||||||
return 1;
|
if ( ! empty( $stored['file'] ) ) {
|
||||||
|
++$removed;
|
||||||
|
}
|
||||||
|
if ( ! $this->dry ) {
|
||||||
|
$this->delete_photo( (int) $row->ID );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( $removed ) {
|
||||||
|
/* translators: %d: number of photos */
|
||||||
|
$this->log( 'info', sprintf( _n( 'Profile photo sync is off: %d stored photo removed.', 'Profile photo sync is off: %d stored photos removed.', $removed, 'm365-login' ), $removed ) );
|
||||||
|
$this->count( 'photos', $removed );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stored photo record of a user.
|
||||||
|
*
|
||||||
|
* @param int $user_id User ID.
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function stored_photo( $user_id ) {
|
||||||
|
$stored = get_user_meta( $user_id, self::META_PHOTO, true );
|
||||||
|
return is_array( $stored ) ? $stored : array();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1273,11 +1389,11 @@ class M365_Login_Sync {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes a user's stored photo.
|
* Deletes a user's stored photo (also hooked to user deletion).
|
||||||
*
|
*
|
||||||
* @param int $user_id User ID.
|
* @param int $user_id User ID.
|
||||||
*/
|
*/
|
||||||
private function delete_photo( $user_id ) {
|
public function delete_photo( $user_id ) {
|
||||||
$stored = get_user_meta( $user_id, self::META_PHOTO, true );
|
$stored = get_user_meta( $user_id, self::META_PHOTO, true );
|
||||||
if ( is_array( $stored ) && ! empty( $stored['file'] ) && 0 === strpos( $stored['file'], self::PHOTO_DIR . '/' ) ) {
|
if ( is_array( $stored ) && ! empty( $stored['file'] ) && 0 === strpos( $stored['file'], self::PHOTO_DIR . '/' ) ) {
|
||||||
wp_delete_file( self::photo_path( $stored['file'] ) );
|
wp_delete_file( self::photo_path( $stored['file'] ) );
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -124,7 +124,7 @@ msgstr "Du hast ungespeicherte Änderungen. Der Sync verwendet die gespeicherten
|
||||||
msgid "Move up"
|
msgid "Move up"
|
||||||
msgstr "Nach oben"
|
msgstr "Nach oben"
|
||||||
|
|
||||||
#: includes/class-m365-login-admin.php:261 includes/class-m365-login-admin.php:300 includes/class-m365-login-admin.php:326 includes/class-m365-login-admin.php:359 includes/class-m365-login-admin.php:514 includes/class-m365-login-sync.php:1495
|
#: includes/class-m365-login-admin.php:261 includes/class-m365-login-admin.php:300 includes/class-m365-login-admin.php:326 includes/class-m365-login-admin.php:359 includes/class-m365-login-admin.php:514 includes/class-m365-login-sync.php:1611
|
||||||
msgid "You are not allowed to do this."
|
msgid "You are not allowed to do this."
|
||||||
msgstr "Dafür fehlt die Berechtigung."
|
msgstr "Dafür fehlt die Berechtigung."
|
||||||
|
|
||||||
|
|
@ -428,8 +428,8 @@ msgid "Selected Microsoft 365 attributes are copied into the WordPress profile o
|
||||||
msgstr "Ausgewählte Microsoft-365-Attribute werden bei jedem Sync ins WordPress-Profil übernommen (Microsoft 365 hat Vorrang). Namen landen in den normalen Profilfeldern, alles andere in Benutzer-Metadaten mit dem Präfix „m365_“ – nutzbar für Themes und andere Plugins – und wird auf der Profilseite angezeigt."
|
msgstr "Ausgewählte Microsoft-365-Attribute werden bei jedem Sync ins WordPress-Profil übernommen (Microsoft 365 hat Vorrang). Namen landen in den normalen Profilfeldern, alles andere in Benutzer-Metadaten mit dem Präfix „m365_“ – nutzbar für Themes und andere Plugins – und wird auf der Profilseite angezeigt."
|
||||||
|
|
||||||
#: includes/class-m365-login-admin.php:643
|
#: includes/class-m365-login-admin.php:643
|
||||||
msgid "Profile photos are stored in wp-content/uploads/m365-login-avatars/ and replace the Gravatar. They are checked about once a day per user."
|
msgid "Profile photos are stored in wp-content/uploads/m365-login-avatars/ and replace the Gravatar. They are compared on every run: changed photos are downloaded again, photos deleted in Microsoft 365 are deleted in WordPress too. Fields and photos you deselect here are removed from the profiles on the next run (first and last name and display name stay)."
|
||||||
msgstr "Profilbilder werden in wp-content/uploads/m365-login-avatars/ gespeichert und ersetzen den Gravatar. Sie werden etwa einmal täglich pro Benutzer geprüft."
|
msgstr "Profilbilder werden in wp-content/uploads/m365-login-avatars/ gespeichert und ersetzen den Gravatar. Sie werden bei jedem Lauf abgeglichen: Geänderte Bilder werden neu geladen, in Microsoft 365 gelöschte Bilder auch in WordPress gelöscht. Felder und Bilder, die du hier abwählst, werden beim nächsten Lauf aus den Profilen entfernt (Vor-, Nach- und Anzeigename bleiben)."
|
||||||
|
|
||||||
#: includes/class-m365-login-admin.php:647
|
#: includes/class-m365-login-admin.php:647
|
||||||
msgid "Disabled and deleted Microsoft 365 accounts"
|
msgid "Disabled and deleted Microsoft 365 accounts"
|
||||||
|
|
@ -1119,7 +1119,7 @@ msgstr "Zu viele Versuche. Bitte 15 Minuten warten."
|
||||||
msgid "Too many sign-in attempts from your connection. Please wait a few minutes and try again."
|
msgid "Too many sign-in attempts from your connection. Please wait a few minutes and try again."
|
||||||
msgstr "Zu viele Anmeldeversuche von dieser Verbindung. Bitte ein paar Minuten warten und erneut versuchen."
|
msgstr "Zu viele Anmeldeversuche von dieser Verbindung. Bitte ein paar Minuten warten und erneut versuchen."
|
||||||
|
|
||||||
#: includes/class-m365-login-auth.php:864 includes/class-m365-login-sync.php:1404
|
#: includes/class-m365-login-auth.php:864 includes/class-m365-login-sync.php:1520
|
||||||
msgid "This account has been deactivated."
|
msgid "This account has been deactivated."
|
||||||
msgstr "Dieses Konto wurde deaktiviert."
|
msgstr "Dieses Konto wurde deaktiviert."
|
||||||
|
|
||||||
|
|
@ -1175,15 +1175,15 @@ msgstr "Das Zertifikat gehört nicht zu diesem privaten Schlüssel."
|
||||||
msgid "The certificate has already expired."
|
msgid "The certificate has already expired."
|
||||||
msgstr "Das Zertifikat ist bereits abgelaufen."
|
msgstr "Das Zertifikat ist bereits abgelaufen."
|
||||||
|
|
||||||
#: includes/class-m365-login-graph.php:375
|
#: includes/class-m365-login-graph.php:434
|
||||||
msgid "Group"
|
msgid "Group"
|
||||||
msgstr "Gruppe"
|
msgstr "Gruppe"
|
||||||
|
|
||||||
#: includes/class-m365-login-graph.php:377
|
#: includes/class-m365-login-graph.php:436
|
||||||
msgid "Security group"
|
msgid "Security group"
|
||||||
msgstr "Sicherheitsgruppe"
|
msgstr "Sicherheitsgruppe"
|
||||||
|
|
||||||
#: includes/class-m365-login-graph.php:379
|
#: includes/class-m365-login-graph.php:438
|
||||||
msgid "Microsoft 365 group"
|
msgid "Microsoft 365 group"
|
||||||
msgstr "Microsoft 365-Gruppe"
|
msgstr "Microsoft 365-Gruppe"
|
||||||
|
|
||||||
|
|
@ -1235,293 +1235,312 @@ msgstr "Die eigene Login-Seite muss eine URL dieser Website sein."
|
||||||
msgid "User sync: \"Delete\" needs a user who receives the posts of deleted accounts. Until one is selected, accounts are deactivated instead."
|
msgid "User sync: \"Delete\" needs a user who receives the posts of deleted accounts. Until one is selected, accounts are deactivated instead."
|
||||||
msgstr "Benutzer-Sync: „Löschen“ braucht einen Benutzer, der die Beiträge gelöschter Konten übernimmt. Bis einer ausgewählt ist, werden Konten stattdessen deaktiviert."
|
msgstr "Benutzer-Sync: „Löschen“ braucht einen Benutzer, der die Beiträge gelöschter Konten übernimmt. Bis einer ausgewählt ist, werden Konten stattdessen deaktiviert."
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:109
|
#: includes/class-m365-login-sync.php:110
|
||||||
msgid "Display name"
|
msgid "Display name"
|
||||||
msgstr "Anzeigename"
|
msgstr "Anzeigename"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:113
|
#: includes/class-m365-login-sync.php:114
|
||||||
msgid "First name"
|
msgid "First name"
|
||||||
msgstr "Vorname"
|
msgstr "Vorname"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:117
|
#: includes/class-m365-login-sync.php:118
|
||||||
msgid "Last name"
|
msgid "Last name"
|
||||||
msgstr "Nachname"
|
msgstr "Nachname"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:121
|
#: includes/class-m365-login-sync.php:122
|
||||||
msgid "Profile photo (used as avatar)"
|
msgid "Profile photo (used as avatar)"
|
||||||
msgstr "Profilbild (als Avatar)"
|
msgstr "Profilbild (als Avatar)"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:125
|
#: includes/class-m365-login-sync.php:126
|
||||||
msgid "Job title"
|
msgid "Job title"
|
||||||
msgstr "Position"
|
msgstr "Position"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:129
|
#: includes/class-m365-login-sync.php:130
|
||||||
msgid "Department"
|
msgid "Department"
|
||||||
msgstr "Abteilung"
|
msgstr "Abteilung"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:133
|
#: includes/class-m365-login-sync.php:134
|
||||||
msgid "Company"
|
msgid "Company"
|
||||||
msgstr "Firma"
|
msgstr "Firma"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:137
|
#: includes/class-m365-login-sync.php:138
|
||||||
msgid "Office"
|
msgid "Office"
|
||||||
msgstr "Büro"
|
msgstr "Büro"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:141
|
#: includes/class-m365-login-sync.php:142
|
||||||
msgid "Employee ID"
|
msgid "Employee ID"
|
||||||
msgstr "Personalnummer"
|
msgstr "Personalnummer"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:145
|
#: includes/class-m365-login-sync.php:146
|
||||||
msgid "Business phone"
|
msgid "Business phone"
|
||||||
msgstr "Telefon (geschäftlich)"
|
msgstr "Telefon (geschäftlich)"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:149
|
#: includes/class-m365-login-sync.php:150
|
||||||
msgid "Mobile phone"
|
msgid "Mobile phone"
|
||||||
msgstr "Mobiltelefon"
|
msgstr "Mobiltelefon"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:153
|
#: includes/class-m365-login-sync.php:154
|
||||||
msgid "Street address"
|
msgid "Street address"
|
||||||
msgstr "Straße"
|
msgstr "Straße"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:157
|
#: includes/class-m365-login-sync.php:158
|
||||||
msgid "Postal code"
|
msgid "Postal code"
|
||||||
msgstr "Postleitzahl"
|
msgstr "Postleitzahl"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:161
|
#: includes/class-m365-login-sync.php:162
|
||||||
msgid "City"
|
msgid "City"
|
||||||
msgstr "Ort"
|
msgstr "Ort"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:165
|
#: includes/class-m365-login-sync.php:166
|
||||||
msgid "State / province"
|
msgid "State / province"
|
||||||
msgstr "Bundesland / Region"
|
msgstr "Bundesland / Region"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:169
|
#: includes/class-m365-login-sync.php:170
|
||||||
msgid "Country"
|
msgid "Country"
|
||||||
msgstr "Land"
|
msgstr "Land"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:173
|
#: includes/class-m365-login-sync.php:174
|
||||||
msgid "Language (sets the admin language if installed)"
|
msgid "Language (sets the admin language if installed)"
|
||||||
msgstr "Sprache (setzt die Backend-Sprache, falls installiert)"
|
msgstr "Sprache (setzt die Backend-Sprache, falls installiert)"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:308
|
#: includes/class-m365-login-sync.php:309
|
||||||
msgid "Another sync is still running. Please try again in a few minutes."
|
msgid "Another sync is still running. Please try again in a few minutes."
|
||||||
msgstr "Ein anderer Sync läuft noch. Bitte versuche es in ein paar Minuten erneut."
|
msgstr "Ein anderer Sync läuft noch. Bitte versuche es in ein paar Minuten erneut."
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:365
|
#: includes/class-m365-login-sync.php:366
|
||||||
msgid "The connection to Microsoft Entra ID is not configured yet."
|
msgid "The connection to Microsoft Entra ID is not configured yet."
|
||||||
msgstr "Die Verbindung zu Microsoft Entra ID ist noch nicht eingerichtet."
|
msgstr "Die Verbindung zu Microsoft Entra ID ist noch nicht eingerichtet."
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:369
|
#: includes/class-m365-login-sync.php:370
|
||||||
msgid "The user sync needs a pinned tenant ID (GUID) on the Connection tab."
|
msgid "The user sync needs a pinned tenant ID (GUID) on the Connection tab."
|
||||||
msgstr "Der Benutzer-Sync braucht eine feste Tenant-ID (GUID) im Tab „Verbindung“."
|
msgstr "Der Benutzer-Sync braucht eine feste Tenant-ID (GUID) im Tab „Verbindung“."
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:373
|
#: includes/class-m365-login-sync.php:374
|
||||||
msgid "The default role does not exist. Please check the sync settings."
|
msgid "The default role does not exist. Please check the sync settings."
|
||||||
msgstr "Die Standardrolle existiert nicht. Bitte prüfe die Sync-Einstellungen."
|
msgstr "Die Standardrolle existiert nicht. Bitte prüfe die Sync-Einstellungen."
|
||||||
|
|
||||||
#. translators: %d: number of users
|
#. translators: %d: number of users
|
||||||
#: includes/class-m365-login-sync.php:385
|
#: includes/class-m365-login-sync.php:386
|
||||||
msgid "%d user read from Microsoft 365."
|
msgid "%d user read from Microsoft 365."
|
||||||
msgid_plural "%d users read from Microsoft 365."
|
msgid_plural "%d users read from Microsoft 365."
|
||||||
msgstr[0] "%d Benutzer aus Microsoft 365 gelesen."
|
msgstr[0] "%d Benutzer aus Microsoft 365 gelesen."
|
||||||
msgstr[1] "%d Benutzer aus Microsoft 365 gelesen."
|
msgstr[1] "%d Benutzer aus Microsoft 365 gelesen."
|
||||||
|
|
||||||
#. translators: 1: number of accounts, 2: limit
|
#. translators: 1: number of accounts, 2: limit
|
||||||
#: includes/class-m365-login-sync.php:435
|
#: includes/class-m365-login-sync.php:443
|
||||||
msgid "Safety stop: %1$d accounts would be deactivated or deleted, more than the limit of %2$d per run. No account was deactivated or deleted. Check the sync groups and the tenant, then run the sync again (the limit can be changed with the m365_login_sync_deprovision_limit filter)."
|
msgid "Safety stop: %1$d accounts would be deactivated or deleted, more than the limit of %2$d per run. No account was deactivated or deleted. Check the sync groups and the tenant, then run the sync again (the limit can be changed with the m365_login_sync_deprovision_limit filter)."
|
||||||
msgstr "Sicherheitsstopp: %1$d Konten würden deaktiviert oder gelöscht, mehr als das Limit von %2$d pro Lauf. Es wurde kein Konto deaktiviert oder gelöscht. Prüfe die Sync-Gruppen und den Tenant und starte den Sync dann erneut (das Limit lässt sich mit dem Filter m365_login_sync_deprovision_limit ändern)."
|
msgstr "Sicherheitsstopp: %1$d Konten würden deaktiviert oder gelöscht, mehr als das Limit von %2$d pro Lauf. Es wurde kein Konto deaktiviert oder gelöscht. Prüfe die Sync-Gruppen und den Tenant und starte den Sync dann erneut (das Limit lässt sich mit dem Filter m365_login_sync_deprovision_limit ändern)."
|
||||||
|
|
||||||
#. translators: %s: user principal name
|
#. translators: %s: user principal name
|
||||||
#: includes/class-m365-login-sync.php:559
|
#: includes/class-m365-login-sync.php:567
|
||||||
msgid "%s: no usable e-mail address, skipped."
|
msgid "%s: no usable e-mail address, skipped."
|
||||||
msgstr "%s: keine verwendbare E-Mail-Adresse, übersprungen."
|
msgstr "%s: keine verwendbare E-Mail-Adresse, übersprungen."
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %s: e-mail address
|
||||||
#: includes/class-m365-login-sync.php:566
|
#: includes/class-m365-login-sync.php:574
|
||||||
msgid "%s: e-mail domain is not on the allow-list, skipped."
|
msgid "%s: e-mail domain is not on the allow-list, skipped."
|
||||||
msgstr "%s: E-Mail-Domain steht nicht auf der Liste erlaubter Domains, übersprungen."
|
msgstr "%s: E-Mail-Domain steht nicht auf der Liste erlaubter Domains, übersprungen."
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %s: e-mail address
|
||||||
#: includes/class-m365-login-sync.php:578
|
#: includes/class-m365-login-sync.php:586
|
||||||
msgid "%s: the WordPress account with this e-mail address is linked to a different Microsoft account, skipped."
|
msgid "%s: the WordPress account with this e-mail address is linked to a different Microsoft account, skipped."
|
||||||
msgstr "%s: Das WordPress-Konto mit dieser E-Mail-Adresse ist mit einem anderen Microsoft-Konto verknüpft, übersprungen."
|
msgstr "%s: Das WordPress-Konto mit dieser E-Mail-Adresse ist mit einem anderen Microsoft-Konto verknüpft, übersprungen."
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %s: e-mail address
|
||||||
#: includes/class-m365-login-sync.php:582
|
#: includes/class-m365-login-sync.php:590
|
||||||
msgid "%s: existing account linked."
|
msgid "%s: existing account linked."
|
||||||
msgstr "%s: bestehendes Konto verknüpft."
|
msgstr "%s: bestehendes Konto verknüpft."
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:596 includes/class-m365-login-sync.php:931 includes/class-m365-login-sync.php:1536
|
#: includes/class-m365-login-sync.php:604 includes/class-m365-login-sync.php:955 includes/class-m365-login-sync.php:1652
|
||||||
msgid "disabled in Microsoft 365"
|
msgid "disabled in Microsoft 365"
|
||||||
msgstr "in Microsoft 365 deaktiviert"
|
msgstr "in Microsoft 365 deaktiviert"
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %s: e-mail address
|
||||||
#: includes/class-m365-login-sync.php:607
|
#: includes/class-m365-login-sync.php:615
|
||||||
msgid "%s: added to this site."
|
msgid "%s: added to this site."
|
||||||
msgstr "%s: zu dieser Website hinzugefügt."
|
msgstr "%s: zu dieser Website hinzugefügt."
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %s: e-mail address
|
||||||
#: includes/class-m365-login-sync.php:616
|
#: includes/class-m365-login-sync.php:624
|
||||||
msgid "%s: reactivated (active in Microsoft 365 again)."
|
msgid "%s: reactivated (active in Microsoft 365 again)."
|
||||||
msgstr "%s: reaktiviert (in Microsoft 365 wieder aktiv)."
|
msgstr "%s: reaktiviert (in Microsoft 365 wieder aktiv)."
|
||||||
|
|
||||||
#. translators: 1: e-mail address, 2: list of changed fields
|
#. translators: 1: e-mail address, 2: list of changed fields
|
||||||
#: includes/class-m365-login-sync.php:627
|
#: includes/class-m365-login-sync.php:635
|
||||||
msgid "%1$s: updated (%2$s)."
|
msgid "%1$s: updated (%2$s)."
|
||||||
msgstr "%1$s: aktualisiert (%2$s)."
|
msgstr "%1$s: aktualisiert (%2$s)."
|
||||||
|
|
||||||
#. translators: 1: e-mail address, 2: role names
|
#. translators: 1: e-mail address, 2: role names
|
||||||
#: includes/class-m365-login-sync.php:653
|
#: includes/class-m365-login-sync.php:661
|
||||||
msgid "%1$s: account created (%2$s)."
|
msgid "%1$s: account created (%2$s)."
|
||||||
msgstr "%1$s: Konto angelegt (%2$s)."
|
msgstr "%1$s: Konto angelegt (%2$s)."
|
||||||
|
|
||||||
#. translators: 1: e-mail address, 2: error message
|
#. translators: 1: e-mail address, 2: error message
|
||||||
#: includes/class-m365-login-sync.php:680
|
#: includes/class-m365-login-sync.php:688
|
||||||
msgid "%1$s: account could not be created: %2$s"
|
msgid "%1$s: account could not be created: %2$s"
|
||||||
msgstr "%1$s: Konto konnte nicht angelegt werden: %2$s"
|
msgstr "%1$s: Konto konnte nicht angelegt werden: %2$s"
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %s: e-mail address
|
||||||
#: includes/class-m365-login-sync.php:738
|
#: includes/class-m365-login-sync.php:746
|
||||||
msgid "%s: e-mail address is used by another WordPress account and was not changed."
|
msgid "%s: e-mail address is used by another WordPress account and was not changed."
|
||||||
msgstr "%s: Die E-Mail-Adresse gehört bereits einem anderen WordPress-Konto und wurde nicht geändert."
|
msgstr "%s: Die E-Mail-Adresse gehört bereits einem anderen WordPress-Konto und wurde nicht geändert."
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %s: e-mail address
|
||||||
#: includes/class-m365-login-sync.php:741
|
#: includes/class-m365-login-sync.php:749
|
||||||
msgid "e-mail"
|
msgid "e-mail"
|
||||||
msgstr "E-Mail"
|
msgstr "E-Mail"
|
||||||
|
|
||||||
|
#. translators: %s: profile field
|
||||||
|
#: includes/class-m365-login-sync.php:799
|
||||||
|
msgid "%s removed"
|
||||||
|
msgstr "%s entfernt"
|
||||||
|
|
||||||
#. translators: 1: e-mail address, 2: error message
|
#. translators: 1: e-mail address, 2: error message
|
||||||
#: includes/class-m365-login-sync.php:785
|
#: includes/class-m365-login-sync.php:809
|
||||||
msgid "%1$s: profile could not be updated: %2$s"
|
msgid "%1$s: profile could not be updated: %2$s"
|
||||||
msgstr "%1$s: Profil konnte nicht aktualisiert werden: %2$s"
|
msgstr "%1$s: Profil konnte nicht aktualisiert werden: %2$s"
|
||||||
|
|
||||||
#. translators: %s: role names
|
#. translators: %s: role names
|
||||||
#: includes/class-m365-login-sync.php:891
|
#: includes/class-m365-login-sync.php:915
|
||||||
msgid "roles: %s"
|
msgid "roles: %s"
|
||||||
msgstr "Rollen: %s"
|
msgstr "Rollen: %s"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:926 includes/class-m365-login-sync.php:1537
|
#: includes/class-m365-login-sync.php:950 includes/class-m365-login-sync.php:1653
|
||||||
msgid "deleted in Microsoft 365"
|
msgid "deleted in Microsoft 365"
|
||||||
msgstr "in Microsoft 365 gelöscht"
|
msgstr "in Microsoft 365 gelöscht"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:934 includes/class-m365-login-sync.php:1538
|
#: includes/class-m365-login-sync.php:958 includes/class-m365-login-sync.php:1654
|
||||||
msgid "no longer a member of the sync groups"
|
msgid "no longer a member of the sync groups"
|
||||||
msgstr "kein Mitglied der Sync-Gruppen mehr"
|
msgstr "kein Mitglied der Sync-Gruppen mehr"
|
||||||
|
|
||||||
#. translators: 1: e-mail address, 2: reason
|
#. translators: 1: e-mail address, 2: reason
|
||||||
#: includes/class-m365-login-sync.php:954
|
#: includes/class-m365-login-sync.php:978
|
||||||
msgid "%1$s: %2$s, but the account is protected (administrator or your own account) and was not changed."
|
msgid "%1$s: %2$s, but the account is protected (administrator or your own account) and was not changed."
|
||||||
msgstr "%1$s: %2$s, das Konto ist aber geschützt (Administrator oder dein eigenes Konto) und wurde nicht geändert."
|
msgstr "%1$s: %2$s, das Konto ist aber geschützt (Administrator oder dein eigenes Konto) und wurde nicht geändert."
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %s: e-mail address
|
||||||
#: includes/class-m365-login-sync.php:987
|
#: includes/class-m365-login-sync.php:1011
|
||||||
msgid "%s: no valid user to receive the content is selected, so the account is deactivated instead of deleted."
|
msgid "%s: no valid user to receive the content is selected, so the account is deactivated instead of deleted."
|
||||||
msgstr "%s: Es ist kein gültiger Benutzer für die Übernahme der Inhalte ausgewählt, deshalb wird das Konto deaktiviert statt gelöscht."
|
msgstr "%s: Es ist kein gültiger Benutzer für die Übernahme der Inhalte ausgewählt, deshalb wird das Konto deaktiviert statt gelöscht."
|
||||||
|
|
||||||
#. translators: 1: e-mail address, 2: reason
|
#. translators: 1: e-mail address, 2: reason
|
||||||
#: includes/class-m365-login-sync.php:996
|
#: includes/class-m365-login-sync.php:1020
|
||||||
msgid "%1$s: account deleted (%2$s)."
|
msgid "%1$s: account deleted (%2$s)."
|
||||||
msgstr "%1$s: Konto gelöscht (%2$s)."
|
msgstr "%1$s: Konto gelöscht (%2$s)."
|
||||||
|
|
||||||
#. translators: 1: e-mail address, 2: reason
|
#. translators: 1: e-mail address, 2: reason
|
||||||
#: includes/class-m365-login-sync.php:1006
|
#: includes/class-m365-login-sync.php:1029
|
||||||
msgid "%1$s: account deactivated (%2$s)."
|
msgid "%1$s: account deactivated (%2$s)."
|
||||||
msgstr "%1$s: Konto deaktiviert (%2$s)."
|
msgstr "%1$s: Konto deaktiviert (%2$s)."
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1085
|
#: includes/class-m365-login-sync.php:1108
|
||||||
msgid "Microsoft Graph refused the request. Grant the application permissions \"User.Read.All\" and \"GroupMember.Read.All\" with admin consent in Entra ID."
|
msgid "Microsoft Graph refused the request. Grant the application permissions \"User.Read.All\" and \"GroupMember.Read.All\" with admin consent in Entra ID."
|
||||||
msgstr "Microsoft Graph hat die Anfrage abgelehnt. Erteile in Entra ID die Anwendungsberechtigungen „User.Read.All“ und „GroupMember.Read.All“ mit Administratorzustimmung."
|
msgstr "Microsoft Graph hat die Anfrage abgelehnt. Erteile in Entra ID die Anwendungsberechtigungen „User.Read.All“ und „GroupMember.Read.All“ mit Administratorzustimmung."
|
||||||
|
|
||||||
#. translators: %s: error message
|
#. translators: %s: error message
|
||||||
#: includes/class-m365-login-sync.php:1088
|
#: includes/class-m365-login-sync.php:1111
|
||||||
msgid "Microsoft Graph error: %s"
|
msgid "Microsoft Graph error: %s"
|
||||||
msgstr "Microsoft-Graph-Fehler: %s"
|
msgstr "Microsoft-Graph-Fehler: %s"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1106
|
#: includes/class-m365-login-sync.php:1129
|
||||||
msgid "Log truncated."
|
msgid "Log truncated."
|
||||||
msgstr "Protokoll gekürzt."
|
msgstr "Protokoll gekürzt."
|
||||||
|
|
||||||
#. translators: 1: e-mail address, 2: error message
|
#. translators: 1: e-mail address, 2: error message
|
||||||
#: includes/class-m365-login-sync.php:1168
|
#: includes/class-m365-login-sync.php:1205
|
||||||
msgid "%1$s: profile photo could not be read: %2$s"
|
msgid "%1$s: profile photo could not be read: %2$s"
|
||||||
msgstr "%1$s: Profilbild konnte nicht gelesen werden: %2$s"
|
msgstr "%1$s: Profilbild konnte nicht gelesen werden: %2$s"
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %s: e-mail address
|
||||||
#: includes/class-m365-login-sync.php:1176
|
#: includes/class-m365-login-sync.php:1229 includes/class-m365-login-sync.php:1272
|
||||||
msgid "%s: profile photo removed."
|
msgid "%s: profile photo updated."
|
||||||
msgstr "%s: Profilbild entfernt."
|
msgstr "%s: Profilbild aktualisiert."
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %s: e-mail address
|
||||||
#: includes/class-m365-login-sync.php:1192
|
#: includes/class-m365-login-sync.php:1248
|
||||||
msgid "%s: profile photo could not be downloaded."
|
msgid "%s: profile photo could not be downloaded."
|
||||||
msgstr "%s: Profilbild konnte nicht heruntergeladen werden."
|
msgstr "%s: Profilbild konnte nicht heruntergeladen werden."
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %s: e-mail address
|
||||||
#: includes/class-m365-login-sync.php:1199
|
#: includes/class-m365-login-sync.php:1255
|
||||||
msgid "%s: profile photo is not a valid image or could not be saved."
|
msgid "%s: profile photo is not a valid image or could not be saved."
|
||||||
msgstr "%s: Profilbild ist kein gültiges Bild oder konnte nicht gespeichert werden."
|
msgstr "%s: Profilbild ist kein gültiges Bild oder konnte nicht gespeichert werden."
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %d: number of photos
|
||||||
#: includes/class-m365-login-sync.php:1216
|
#: includes/class-m365-login-sync.php:1278
|
||||||
msgid "%s: profile photo updated."
|
msgid "%d changed profile photo will be downloaded in the next run (download limit per run reached)."
|
||||||
msgstr "%s: Profilbild aktualisiert."
|
msgid_plural "%d changed profile photos will be downloaded in the next run (download limit per run reached)."
|
||||||
|
msgstr[0] "%d geändertes Profilbild wird im nächsten Lauf heruntergeladen (Download-Limit pro Lauf erreicht)."
|
||||||
|
msgstr[1] "%d geänderte Profilbilder werden im nächsten Lauf heruntergeladen (Download-Limit pro Lauf erreicht)."
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1433 includes/class-m365-login-sync.php:1566
|
#. translators: %s: e-mail address
|
||||||
|
#: includes/class-m365-login-sync.php:1293
|
||||||
|
msgid "%s: profile photo removed."
|
||||||
|
msgstr "%s: Profilbild entfernt."
|
||||||
|
|
||||||
|
#. translators: %d: number of photos
|
||||||
|
#: includes/class-m365-login-sync.php:1321
|
||||||
|
msgid "Profile photo sync is off: %d stored photo removed."
|
||||||
|
msgid_plural "Profile photo sync is off: %d stored photos removed."
|
||||||
|
msgstr[0] "Profilbild-Sync ist aus: %d gespeichertes Profilbild entfernt."
|
||||||
|
msgstr[1] "Profilbild-Sync ist aus: %d gespeicherte Profilbilder entfernt."
|
||||||
|
|
||||||
|
#: includes/class-m365-login-sync.php:1549 includes/class-m365-login-sync.php:1682
|
||||||
msgid "Microsoft 365"
|
msgid "Microsoft 365"
|
||||||
msgstr "Microsoft 365"
|
msgstr "Microsoft 365"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1451
|
#: includes/class-m365-login-sync.php:1567
|
||||||
msgid "Deactivated"
|
msgid "Deactivated"
|
||||||
msgstr "Deaktiviert"
|
msgstr "Deaktiviert"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1454
|
#: includes/class-m365-login-sync.php:1570
|
||||||
msgid "Imported"
|
msgid "Imported"
|
||||||
msgstr "Importiert"
|
msgstr "Importiert"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1456
|
#: includes/class-m365-login-sync.php:1572
|
||||||
msgid "Linked"
|
msgid "Linked"
|
||||||
msgstr "Verknüpft"
|
msgstr "Verknüpft"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1484
|
#: includes/class-m365-login-sync.php:1600
|
||||||
msgid "Reactivate"
|
msgid "Reactivate"
|
||||||
msgstr "Reaktivieren"
|
msgstr "Reaktivieren"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1484
|
#: includes/class-m365-login-sync.php:1600
|
||||||
msgid "Deactivate"
|
msgid "Deactivate"
|
||||||
msgstr "Deaktivieren"
|
msgstr "Deaktivieren"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1517
|
#: includes/class-m365-login-sync.php:1633
|
||||||
msgid "The account has been deactivated and signed out everywhere."
|
msgid "The account has been deactivated and signed out everywhere."
|
||||||
msgstr "Das Konto wurde deaktiviert und überall abgemeldet."
|
msgstr "Das Konto wurde deaktiviert und überall abgemeldet."
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1518
|
#: includes/class-m365-login-sync.php:1634
|
||||||
msgid "The account has been reactivated."
|
msgid "The account has been reactivated."
|
||||||
msgstr "Das Konto wurde reaktiviert."
|
msgstr "Das Konto wurde reaktiviert."
|
||||||
|
|
||||||
#. translators: 1: date, 2: reason
|
#. translators: 1: date, 2: reason
|
||||||
#: includes/class-m365-login-sync.php:1542
|
#: includes/class-m365-login-sync.php:1658
|
||||||
msgid "Deactivated since %1$s (%2$s)"
|
msgid "Deactivated since %1$s (%2$s)"
|
||||||
msgstr "Deaktiviert seit %1$s (%2$s)"
|
msgstr "Deaktiviert seit %1$s (%2$s)"
|
||||||
|
|
||||||
#. translators: 1: date, 2: reason
|
#. translators: 1: date, 2: reason
|
||||||
#: includes/class-m365-login-sync.php:1544
|
#: includes/class-m365-login-sync.php:1660
|
||||||
msgid "manually"
|
msgid "manually"
|
||||||
msgstr "manuell"
|
msgstr "manuell"
|
||||||
|
|
||||||
#. translators: 1: date, 2: reason
|
#. translators: 1: date, 2: reason
|
||||||
#: includes/class-m365-login-sync.php:1546
|
#: includes/class-m365-login-sync.php:1662
|
||||||
msgid "Status"
|
msgid "Status"
|
||||||
msgstr "Status"
|
msgstr "Status"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1549
|
#: includes/class-m365-login-sync.php:1665
|
||||||
msgid "Object ID"
|
msgid "Object ID"
|
||||||
msgstr "Objekt-ID"
|
msgstr "Objekt-ID"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1553
|
#: includes/class-m365-login-sync.php:1669
|
||||||
msgid "Last sync"
|
msgid "Last sync"
|
||||||
msgstr "Letzter Sync"
|
msgstr "Letzter Sync"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1575
|
#: includes/class-m365-login-sync.php:1691
|
||||||
msgid "These values are managed by the Microsoft 365 user sync and overwritten on the next run."
|
msgid "These values are managed by the Microsoft 365 user sync and overwritten on the next run."
|
||||||
msgstr "Diese Werte verwaltet der Microsoft-365-Benutzer-Sync; sie werden beim nächsten Lauf überschrieben."
|
msgstr "Diese Werte verwaltet der Microsoft-365-Benutzer-Sync; sie werden beim nächsten Lauf überschrieben."
|
||||||
|
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -124,7 +124,7 @@ msgstr "Sie haben ungespeicherte Änderungen. Der Sync verwendet die gespeichert
|
||||||
msgid "Move up"
|
msgid "Move up"
|
||||||
msgstr "Nach oben"
|
msgstr "Nach oben"
|
||||||
|
|
||||||
#: includes/class-m365-login-admin.php:261 includes/class-m365-login-admin.php:300 includes/class-m365-login-admin.php:326 includes/class-m365-login-admin.php:359 includes/class-m365-login-admin.php:514 includes/class-m365-login-sync.php:1495
|
#: includes/class-m365-login-admin.php:261 includes/class-m365-login-admin.php:300 includes/class-m365-login-admin.php:326 includes/class-m365-login-admin.php:359 includes/class-m365-login-admin.php:514 includes/class-m365-login-sync.php:1611
|
||||||
msgid "You are not allowed to do this."
|
msgid "You are not allowed to do this."
|
||||||
msgstr "Dafür fehlt die Berechtigung."
|
msgstr "Dafür fehlt die Berechtigung."
|
||||||
|
|
||||||
|
|
@ -428,8 +428,8 @@ msgid "Selected Microsoft 365 attributes are copied into the WordPress profile o
|
||||||
msgstr "Ausgewählte Microsoft-365-Attribute werden bei jedem Sync ins WordPress-Profil übernommen (Microsoft 365 hat Vorrang). Namen landen in den normalen Profilfeldern, alles andere in Benutzer-Metadaten mit dem Präfix „m365_“ – nutzbar für Themes und andere Plugins – und wird auf der Profilseite angezeigt."
|
msgstr "Ausgewählte Microsoft-365-Attribute werden bei jedem Sync ins WordPress-Profil übernommen (Microsoft 365 hat Vorrang). Namen landen in den normalen Profilfeldern, alles andere in Benutzer-Metadaten mit dem Präfix „m365_“ – nutzbar für Themes und andere Plugins – und wird auf der Profilseite angezeigt."
|
||||||
|
|
||||||
#: includes/class-m365-login-admin.php:643
|
#: includes/class-m365-login-admin.php:643
|
||||||
msgid "Profile photos are stored in wp-content/uploads/m365-login-avatars/ and replace the Gravatar. They are checked about once a day per user."
|
msgid "Profile photos are stored in wp-content/uploads/m365-login-avatars/ and replace the Gravatar. They are compared on every run: changed photos are downloaded again, photos deleted in Microsoft 365 are deleted in WordPress too. Fields and photos you deselect here are removed from the profiles on the next run (first and last name and display name stay)."
|
||||||
msgstr "Profilbilder werden in wp-content/uploads/m365-login-avatars/ gespeichert und ersetzen den Gravatar. Sie werden etwa einmal täglich pro Benutzer geprüft."
|
msgstr "Profilbilder werden in wp-content/uploads/m365-login-avatars/ gespeichert und ersetzen den Gravatar. Sie werden bei jedem Lauf abgeglichen: Geänderte Bilder werden neu geladen, in Microsoft 365 gelöschte Bilder auch in WordPress gelöscht. Felder und Bilder, die Sie hier abwählen, werden beim nächsten Lauf aus den Profilen entfernt (Vor-, Nach- und Anzeigename bleiben)."
|
||||||
|
|
||||||
#: includes/class-m365-login-admin.php:647
|
#: includes/class-m365-login-admin.php:647
|
||||||
msgid "Disabled and deleted Microsoft 365 accounts"
|
msgid "Disabled and deleted Microsoft 365 accounts"
|
||||||
|
|
@ -1119,7 +1119,7 @@ msgstr "Zu viele Versuche. Bitte 15 Minuten warten."
|
||||||
msgid "Too many sign-in attempts from your connection. Please wait a few minutes and try again."
|
msgid "Too many sign-in attempts from your connection. Please wait a few minutes and try again."
|
||||||
msgstr "Zu viele Anmeldeversuche von dieser Verbindung. Bitte ein paar Minuten warten und erneut versuchen."
|
msgstr "Zu viele Anmeldeversuche von dieser Verbindung. Bitte ein paar Minuten warten und erneut versuchen."
|
||||||
|
|
||||||
#: includes/class-m365-login-auth.php:864 includes/class-m365-login-sync.php:1404
|
#: includes/class-m365-login-auth.php:864 includes/class-m365-login-sync.php:1520
|
||||||
msgid "This account has been deactivated."
|
msgid "This account has been deactivated."
|
||||||
msgstr "Dieses Konto wurde deaktiviert."
|
msgstr "Dieses Konto wurde deaktiviert."
|
||||||
|
|
||||||
|
|
@ -1175,15 +1175,15 @@ msgstr "Das Zertifikat gehört nicht zu diesem privaten Schlüssel."
|
||||||
msgid "The certificate has already expired."
|
msgid "The certificate has already expired."
|
||||||
msgstr "Das Zertifikat ist bereits abgelaufen."
|
msgstr "Das Zertifikat ist bereits abgelaufen."
|
||||||
|
|
||||||
#: includes/class-m365-login-graph.php:375
|
#: includes/class-m365-login-graph.php:434
|
||||||
msgid "Group"
|
msgid "Group"
|
||||||
msgstr "Gruppe"
|
msgstr "Gruppe"
|
||||||
|
|
||||||
#: includes/class-m365-login-graph.php:377
|
#: includes/class-m365-login-graph.php:436
|
||||||
msgid "Security group"
|
msgid "Security group"
|
||||||
msgstr "Sicherheitsgruppe"
|
msgstr "Sicherheitsgruppe"
|
||||||
|
|
||||||
#: includes/class-m365-login-graph.php:379
|
#: includes/class-m365-login-graph.php:438
|
||||||
msgid "Microsoft 365 group"
|
msgid "Microsoft 365 group"
|
||||||
msgstr "Microsoft 365-Gruppe"
|
msgstr "Microsoft 365-Gruppe"
|
||||||
|
|
||||||
|
|
@ -1235,293 +1235,312 @@ msgstr "Die eigene Login-Seite muss eine URL dieser Website sein."
|
||||||
msgid "User sync: \"Delete\" needs a user who receives the posts of deleted accounts. Until one is selected, accounts are deactivated instead."
|
msgid "User sync: \"Delete\" needs a user who receives the posts of deleted accounts. Until one is selected, accounts are deactivated instead."
|
||||||
msgstr "Benutzer-Sync: „Löschen“ braucht einen Benutzer, der die Beiträge gelöschter Konten übernimmt. Bis einer ausgewählt ist, werden Konten stattdessen deaktiviert."
|
msgstr "Benutzer-Sync: „Löschen“ braucht einen Benutzer, der die Beiträge gelöschter Konten übernimmt. Bis einer ausgewählt ist, werden Konten stattdessen deaktiviert."
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:109
|
#: includes/class-m365-login-sync.php:110
|
||||||
msgid "Display name"
|
msgid "Display name"
|
||||||
msgstr "Anzeigename"
|
msgstr "Anzeigename"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:113
|
#: includes/class-m365-login-sync.php:114
|
||||||
msgid "First name"
|
msgid "First name"
|
||||||
msgstr "Vorname"
|
msgstr "Vorname"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:117
|
#: includes/class-m365-login-sync.php:118
|
||||||
msgid "Last name"
|
msgid "Last name"
|
||||||
msgstr "Nachname"
|
msgstr "Nachname"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:121
|
#: includes/class-m365-login-sync.php:122
|
||||||
msgid "Profile photo (used as avatar)"
|
msgid "Profile photo (used as avatar)"
|
||||||
msgstr "Profilbild (als Avatar)"
|
msgstr "Profilbild (als Avatar)"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:125
|
#: includes/class-m365-login-sync.php:126
|
||||||
msgid "Job title"
|
msgid "Job title"
|
||||||
msgstr "Position"
|
msgstr "Position"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:129
|
#: includes/class-m365-login-sync.php:130
|
||||||
msgid "Department"
|
msgid "Department"
|
||||||
msgstr "Abteilung"
|
msgstr "Abteilung"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:133
|
#: includes/class-m365-login-sync.php:134
|
||||||
msgid "Company"
|
msgid "Company"
|
||||||
msgstr "Firma"
|
msgstr "Firma"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:137
|
#: includes/class-m365-login-sync.php:138
|
||||||
msgid "Office"
|
msgid "Office"
|
||||||
msgstr "Büro"
|
msgstr "Büro"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:141
|
#: includes/class-m365-login-sync.php:142
|
||||||
msgid "Employee ID"
|
msgid "Employee ID"
|
||||||
msgstr "Personalnummer"
|
msgstr "Personalnummer"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:145
|
#: includes/class-m365-login-sync.php:146
|
||||||
msgid "Business phone"
|
msgid "Business phone"
|
||||||
msgstr "Telefon (geschäftlich)"
|
msgstr "Telefon (geschäftlich)"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:149
|
#: includes/class-m365-login-sync.php:150
|
||||||
msgid "Mobile phone"
|
msgid "Mobile phone"
|
||||||
msgstr "Mobiltelefon"
|
msgstr "Mobiltelefon"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:153
|
#: includes/class-m365-login-sync.php:154
|
||||||
msgid "Street address"
|
msgid "Street address"
|
||||||
msgstr "Straße"
|
msgstr "Straße"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:157
|
#: includes/class-m365-login-sync.php:158
|
||||||
msgid "Postal code"
|
msgid "Postal code"
|
||||||
msgstr "Postleitzahl"
|
msgstr "Postleitzahl"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:161
|
#: includes/class-m365-login-sync.php:162
|
||||||
msgid "City"
|
msgid "City"
|
||||||
msgstr "Ort"
|
msgstr "Ort"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:165
|
#: includes/class-m365-login-sync.php:166
|
||||||
msgid "State / province"
|
msgid "State / province"
|
||||||
msgstr "Bundesland / Region"
|
msgstr "Bundesland / Region"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:169
|
#: includes/class-m365-login-sync.php:170
|
||||||
msgid "Country"
|
msgid "Country"
|
||||||
msgstr "Land"
|
msgstr "Land"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:173
|
#: includes/class-m365-login-sync.php:174
|
||||||
msgid "Language (sets the admin language if installed)"
|
msgid "Language (sets the admin language if installed)"
|
||||||
msgstr "Sprache (setzt die Backend-Sprache, falls installiert)"
|
msgstr "Sprache (setzt die Backend-Sprache, falls installiert)"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:308
|
#: includes/class-m365-login-sync.php:309
|
||||||
msgid "Another sync is still running. Please try again in a few minutes."
|
msgid "Another sync is still running. Please try again in a few minutes."
|
||||||
msgstr "Ein anderer Sync läuft noch. Bitte versuchen Sie es in ein paar Minuten erneut."
|
msgstr "Ein anderer Sync läuft noch. Bitte versuchen Sie es in ein paar Minuten erneut."
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:365
|
#: includes/class-m365-login-sync.php:366
|
||||||
msgid "The connection to Microsoft Entra ID is not configured yet."
|
msgid "The connection to Microsoft Entra ID is not configured yet."
|
||||||
msgstr "Die Verbindung zu Microsoft Entra ID ist noch nicht eingerichtet."
|
msgstr "Die Verbindung zu Microsoft Entra ID ist noch nicht eingerichtet."
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:369
|
#: includes/class-m365-login-sync.php:370
|
||||||
msgid "The user sync needs a pinned tenant ID (GUID) on the Connection tab."
|
msgid "The user sync needs a pinned tenant ID (GUID) on the Connection tab."
|
||||||
msgstr "Der Benutzer-Sync braucht eine feste Tenant-ID (GUID) im Tab „Verbindung“."
|
msgstr "Der Benutzer-Sync braucht eine feste Tenant-ID (GUID) im Tab „Verbindung“."
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:373
|
#: includes/class-m365-login-sync.php:374
|
||||||
msgid "The default role does not exist. Please check the sync settings."
|
msgid "The default role does not exist. Please check the sync settings."
|
||||||
msgstr "Die Standardrolle existiert nicht. Bitte prüfen Sie die Sync-Einstellungen."
|
msgstr "Die Standardrolle existiert nicht. Bitte prüfen Sie die Sync-Einstellungen."
|
||||||
|
|
||||||
#. translators: %d: number of users
|
#. translators: %d: number of users
|
||||||
#: includes/class-m365-login-sync.php:385
|
#: includes/class-m365-login-sync.php:386
|
||||||
msgid "%d user read from Microsoft 365."
|
msgid "%d user read from Microsoft 365."
|
||||||
msgid_plural "%d users read from Microsoft 365."
|
msgid_plural "%d users read from Microsoft 365."
|
||||||
msgstr[0] "%d Benutzer aus Microsoft 365 gelesen."
|
msgstr[0] "%d Benutzer aus Microsoft 365 gelesen."
|
||||||
msgstr[1] "%d Benutzer aus Microsoft 365 gelesen."
|
msgstr[1] "%d Benutzer aus Microsoft 365 gelesen."
|
||||||
|
|
||||||
#. translators: 1: number of accounts, 2: limit
|
#. translators: 1: number of accounts, 2: limit
|
||||||
#: includes/class-m365-login-sync.php:435
|
#: includes/class-m365-login-sync.php:443
|
||||||
msgid "Safety stop: %1$d accounts would be deactivated or deleted, more than the limit of %2$d per run. No account was deactivated or deleted. Check the sync groups and the tenant, then run the sync again (the limit can be changed with the m365_login_sync_deprovision_limit filter)."
|
msgid "Safety stop: %1$d accounts would be deactivated or deleted, more than the limit of %2$d per run. No account was deactivated or deleted. Check the sync groups and the tenant, then run the sync again (the limit can be changed with the m365_login_sync_deprovision_limit filter)."
|
||||||
msgstr "Sicherheitsstopp: %1$d Konten würden deaktiviert oder gelöscht, mehr als das Limit von %2$d pro Lauf. Es wurde kein Konto deaktiviert oder gelöscht. Prüfen Sie die Sync-Gruppen und den Tenant und starten Sie den Sync dann erneut (das Limit lässt sich mit dem Filter m365_login_sync_deprovision_limit ändern)."
|
msgstr "Sicherheitsstopp: %1$d Konten würden deaktiviert oder gelöscht, mehr als das Limit von %2$d pro Lauf. Es wurde kein Konto deaktiviert oder gelöscht. Prüfen Sie die Sync-Gruppen und den Tenant und starten Sie den Sync dann erneut (das Limit lässt sich mit dem Filter m365_login_sync_deprovision_limit ändern)."
|
||||||
|
|
||||||
#. translators: %s: user principal name
|
#. translators: %s: user principal name
|
||||||
#: includes/class-m365-login-sync.php:559
|
#: includes/class-m365-login-sync.php:567
|
||||||
msgid "%s: no usable e-mail address, skipped."
|
msgid "%s: no usable e-mail address, skipped."
|
||||||
msgstr "%s: keine verwendbare E-Mail-Adresse, übersprungen."
|
msgstr "%s: keine verwendbare E-Mail-Adresse, übersprungen."
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %s: e-mail address
|
||||||
#: includes/class-m365-login-sync.php:566
|
#: includes/class-m365-login-sync.php:574
|
||||||
msgid "%s: e-mail domain is not on the allow-list, skipped."
|
msgid "%s: e-mail domain is not on the allow-list, skipped."
|
||||||
msgstr "%s: E-Mail-Domain steht nicht auf der Liste erlaubter Domains, übersprungen."
|
msgstr "%s: E-Mail-Domain steht nicht auf der Liste erlaubter Domains, übersprungen."
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %s: e-mail address
|
||||||
#: includes/class-m365-login-sync.php:578
|
#: includes/class-m365-login-sync.php:586
|
||||||
msgid "%s: the WordPress account with this e-mail address is linked to a different Microsoft account, skipped."
|
msgid "%s: the WordPress account with this e-mail address is linked to a different Microsoft account, skipped."
|
||||||
msgstr "%s: Das WordPress-Konto mit dieser E-Mail-Adresse ist mit einem anderen Microsoft-Konto verknüpft, übersprungen."
|
msgstr "%s: Das WordPress-Konto mit dieser E-Mail-Adresse ist mit einem anderen Microsoft-Konto verknüpft, übersprungen."
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %s: e-mail address
|
||||||
#: includes/class-m365-login-sync.php:582
|
#: includes/class-m365-login-sync.php:590
|
||||||
msgid "%s: existing account linked."
|
msgid "%s: existing account linked."
|
||||||
msgstr "%s: bestehendes Konto verknüpft."
|
msgstr "%s: bestehendes Konto verknüpft."
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:596 includes/class-m365-login-sync.php:931 includes/class-m365-login-sync.php:1536
|
#: includes/class-m365-login-sync.php:604 includes/class-m365-login-sync.php:955 includes/class-m365-login-sync.php:1652
|
||||||
msgid "disabled in Microsoft 365"
|
msgid "disabled in Microsoft 365"
|
||||||
msgstr "in Microsoft 365 deaktiviert"
|
msgstr "in Microsoft 365 deaktiviert"
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %s: e-mail address
|
||||||
#: includes/class-m365-login-sync.php:607
|
#: includes/class-m365-login-sync.php:615
|
||||||
msgid "%s: added to this site."
|
msgid "%s: added to this site."
|
||||||
msgstr "%s: zu dieser Website hinzugefügt."
|
msgstr "%s: zu dieser Website hinzugefügt."
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %s: e-mail address
|
||||||
#: includes/class-m365-login-sync.php:616
|
#: includes/class-m365-login-sync.php:624
|
||||||
msgid "%s: reactivated (active in Microsoft 365 again)."
|
msgid "%s: reactivated (active in Microsoft 365 again)."
|
||||||
msgstr "%s: reaktiviert (in Microsoft 365 wieder aktiv)."
|
msgstr "%s: reaktiviert (in Microsoft 365 wieder aktiv)."
|
||||||
|
|
||||||
#. translators: 1: e-mail address, 2: list of changed fields
|
#. translators: 1: e-mail address, 2: list of changed fields
|
||||||
#: includes/class-m365-login-sync.php:627
|
#: includes/class-m365-login-sync.php:635
|
||||||
msgid "%1$s: updated (%2$s)."
|
msgid "%1$s: updated (%2$s)."
|
||||||
msgstr "%1$s: aktualisiert (%2$s)."
|
msgstr "%1$s: aktualisiert (%2$s)."
|
||||||
|
|
||||||
#. translators: 1: e-mail address, 2: role names
|
#. translators: 1: e-mail address, 2: role names
|
||||||
#: includes/class-m365-login-sync.php:653
|
#: includes/class-m365-login-sync.php:661
|
||||||
msgid "%1$s: account created (%2$s)."
|
msgid "%1$s: account created (%2$s)."
|
||||||
msgstr "%1$s: Konto angelegt (%2$s)."
|
msgstr "%1$s: Konto angelegt (%2$s)."
|
||||||
|
|
||||||
#. translators: 1: e-mail address, 2: error message
|
#. translators: 1: e-mail address, 2: error message
|
||||||
#: includes/class-m365-login-sync.php:680
|
#: includes/class-m365-login-sync.php:688
|
||||||
msgid "%1$s: account could not be created: %2$s"
|
msgid "%1$s: account could not be created: %2$s"
|
||||||
msgstr "%1$s: Konto konnte nicht angelegt werden: %2$s"
|
msgstr "%1$s: Konto konnte nicht angelegt werden: %2$s"
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %s: e-mail address
|
||||||
#: includes/class-m365-login-sync.php:738
|
#: includes/class-m365-login-sync.php:746
|
||||||
msgid "%s: e-mail address is used by another WordPress account and was not changed."
|
msgid "%s: e-mail address is used by another WordPress account and was not changed."
|
||||||
msgstr "%s: Die E-Mail-Adresse gehört bereits einem anderen WordPress-Konto und wurde nicht geändert."
|
msgstr "%s: Die E-Mail-Adresse gehört bereits einem anderen WordPress-Konto und wurde nicht geändert."
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %s: e-mail address
|
||||||
#: includes/class-m365-login-sync.php:741
|
#: includes/class-m365-login-sync.php:749
|
||||||
msgid "e-mail"
|
msgid "e-mail"
|
||||||
msgstr "E-Mail"
|
msgstr "E-Mail"
|
||||||
|
|
||||||
|
#. translators: %s: profile field
|
||||||
|
#: includes/class-m365-login-sync.php:799
|
||||||
|
msgid "%s removed"
|
||||||
|
msgstr "%s entfernt"
|
||||||
|
|
||||||
#. translators: 1: e-mail address, 2: error message
|
#. translators: 1: e-mail address, 2: error message
|
||||||
#: includes/class-m365-login-sync.php:785
|
#: includes/class-m365-login-sync.php:809
|
||||||
msgid "%1$s: profile could not be updated: %2$s"
|
msgid "%1$s: profile could not be updated: %2$s"
|
||||||
msgstr "%1$s: Profil konnte nicht aktualisiert werden: %2$s"
|
msgstr "%1$s: Profil konnte nicht aktualisiert werden: %2$s"
|
||||||
|
|
||||||
#. translators: %s: role names
|
#. translators: %s: role names
|
||||||
#: includes/class-m365-login-sync.php:891
|
#: includes/class-m365-login-sync.php:915
|
||||||
msgid "roles: %s"
|
msgid "roles: %s"
|
||||||
msgstr "Rollen: %s"
|
msgstr "Rollen: %s"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:926 includes/class-m365-login-sync.php:1537
|
#: includes/class-m365-login-sync.php:950 includes/class-m365-login-sync.php:1653
|
||||||
msgid "deleted in Microsoft 365"
|
msgid "deleted in Microsoft 365"
|
||||||
msgstr "in Microsoft 365 gelöscht"
|
msgstr "in Microsoft 365 gelöscht"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:934 includes/class-m365-login-sync.php:1538
|
#: includes/class-m365-login-sync.php:958 includes/class-m365-login-sync.php:1654
|
||||||
msgid "no longer a member of the sync groups"
|
msgid "no longer a member of the sync groups"
|
||||||
msgstr "kein Mitglied der Sync-Gruppen mehr"
|
msgstr "kein Mitglied der Sync-Gruppen mehr"
|
||||||
|
|
||||||
#. translators: 1: e-mail address, 2: reason
|
#. translators: 1: e-mail address, 2: reason
|
||||||
#: includes/class-m365-login-sync.php:954
|
#: includes/class-m365-login-sync.php:978
|
||||||
msgid "%1$s: %2$s, but the account is protected (administrator or your own account) and was not changed."
|
msgid "%1$s: %2$s, but the account is protected (administrator or your own account) and was not changed."
|
||||||
msgstr "%1$s: %2$s, das Konto ist aber geschützt (Administrator oder Ihr eigenes Konto) und wurde nicht geändert."
|
msgstr "%1$s: %2$s, das Konto ist aber geschützt (Administrator oder Ihr eigenes Konto) und wurde nicht geändert."
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %s: e-mail address
|
||||||
#: includes/class-m365-login-sync.php:987
|
#: includes/class-m365-login-sync.php:1011
|
||||||
msgid "%s: no valid user to receive the content is selected, so the account is deactivated instead of deleted."
|
msgid "%s: no valid user to receive the content is selected, so the account is deactivated instead of deleted."
|
||||||
msgstr "%s: Es ist kein gültiger Benutzer für die Übernahme der Inhalte ausgewählt, deshalb wird das Konto deaktiviert statt gelöscht."
|
msgstr "%s: Es ist kein gültiger Benutzer für die Übernahme der Inhalte ausgewählt, deshalb wird das Konto deaktiviert statt gelöscht."
|
||||||
|
|
||||||
#. translators: 1: e-mail address, 2: reason
|
#. translators: 1: e-mail address, 2: reason
|
||||||
#: includes/class-m365-login-sync.php:996
|
#: includes/class-m365-login-sync.php:1020
|
||||||
msgid "%1$s: account deleted (%2$s)."
|
msgid "%1$s: account deleted (%2$s)."
|
||||||
msgstr "%1$s: Konto gelöscht (%2$s)."
|
msgstr "%1$s: Konto gelöscht (%2$s)."
|
||||||
|
|
||||||
#. translators: 1: e-mail address, 2: reason
|
#. translators: 1: e-mail address, 2: reason
|
||||||
#: includes/class-m365-login-sync.php:1006
|
#: includes/class-m365-login-sync.php:1029
|
||||||
msgid "%1$s: account deactivated (%2$s)."
|
msgid "%1$s: account deactivated (%2$s)."
|
||||||
msgstr "%1$s: Konto deaktiviert (%2$s)."
|
msgstr "%1$s: Konto deaktiviert (%2$s)."
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1085
|
#: includes/class-m365-login-sync.php:1108
|
||||||
msgid "Microsoft Graph refused the request. Grant the application permissions \"User.Read.All\" and \"GroupMember.Read.All\" with admin consent in Entra ID."
|
msgid "Microsoft Graph refused the request. Grant the application permissions \"User.Read.All\" and \"GroupMember.Read.All\" with admin consent in Entra ID."
|
||||||
msgstr "Microsoft Graph hat die Anfrage abgelehnt. Erteilen Sie in Entra ID die Anwendungsberechtigungen „User.Read.All“ und „GroupMember.Read.All“ mit Administratorzustimmung."
|
msgstr "Microsoft Graph hat die Anfrage abgelehnt. Erteilen Sie in Entra ID die Anwendungsberechtigungen „User.Read.All“ und „GroupMember.Read.All“ mit Administratorzustimmung."
|
||||||
|
|
||||||
#. translators: %s: error message
|
#. translators: %s: error message
|
||||||
#: includes/class-m365-login-sync.php:1088
|
#: includes/class-m365-login-sync.php:1111
|
||||||
msgid "Microsoft Graph error: %s"
|
msgid "Microsoft Graph error: %s"
|
||||||
msgstr "Microsoft-Graph-Fehler: %s"
|
msgstr "Microsoft-Graph-Fehler: %s"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1106
|
#: includes/class-m365-login-sync.php:1129
|
||||||
msgid "Log truncated."
|
msgid "Log truncated."
|
||||||
msgstr "Protokoll gekürzt."
|
msgstr "Protokoll gekürzt."
|
||||||
|
|
||||||
#. translators: 1: e-mail address, 2: error message
|
#. translators: 1: e-mail address, 2: error message
|
||||||
#: includes/class-m365-login-sync.php:1168
|
#: includes/class-m365-login-sync.php:1205
|
||||||
msgid "%1$s: profile photo could not be read: %2$s"
|
msgid "%1$s: profile photo could not be read: %2$s"
|
||||||
msgstr "%1$s: Profilbild konnte nicht gelesen werden: %2$s"
|
msgstr "%1$s: Profilbild konnte nicht gelesen werden: %2$s"
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %s: e-mail address
|
||||||
#: includes/class-m365-login-sync.php:1176
|
#: includes/class-m365-login-sync.php:1229 includes/class-m365-login-sync.php:1272
|
||||||
msgid "%s: profile photo removed."
|
msgid "%s: profile photo updated."
|
||||||
msgstr "%s: Profilbild entfernt."
|
msgstr "%s: Profilbild aktualisiert."
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %s: e-mail address
|
||||||
#: includes/class-m365-login-sync.php:1192
|
#: includes/class-m365-login-sync.php:1248
|
||||||
msgid "%s: profile photo could not be downloaded."
|
msgid "%s: profile photo could not be downloaded."
|
||||||
msgstr "%s: Profilbild konnte nicht heruntergeladen werden."
|
msgstr "%s: Profilbild konnte nicht heruntergeladen werden."
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %s: e-mail address
|
||||||
#: includes/class-m365-login-sync.php:1199
|
#: includes/class-m365-login-sync.php:1255
|
||||||
msgid "%s: profile photo is not a valid image or could not be saved."
|
msgid "%s: profile photo is not a valid image or could not be saved."
|
||||||
msgstr "%s: Profilbild ist kein gültiges Bild oder konnte nicht gespeichert werden."
|
msgstr "%s: Profilbild ist kein gültiges Bild oder konnte nicht gespeichert werden."
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %d: number of photos
|
||||||
#: includes/class-m365-login-sync.php:1216
|
#: includes/class-m365-login-sync.php:1278
|
||||||
msgid "%s: profile photo updated."
|
msgid "%d changed profile photo will be downloaded in the next run (download limit per run reached)."
|
||||||
msgstr "%s: Profilbild aktualisiert."
|
msgid_plural "%d changed profile photos will be downloaded in the next run (download limit per run reached)."
|
||||||
|
msgstr[0] "%d geändertes Profilbild wird im nächsten Lauf heruntergeladen (Download-Limit pro Lauf erreicht)."
|
||||||
|
msgstr[1] "%d geänderte Profilbilder werden im nächsten Lauf heruntergeladen (Download-Limit pro Lauf erreicht)."
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1433 includes/class-m365-login-sync.php:1566
|
#. translators: %s: e-mail address
|
||||||
|
#: includes/class-m365-login-sync.php:1293
|
||||||
|
msgid "%s: profile photo removed."
|
||||||
|
msgstr "%s: Profilbild entfernt."
|
||||||
|
|
||||||
|
#. translators: %d: number of photos
|
||||||
|
#: includes/class-m365-login-sync.php:1321
|
||||||
|
msgid "Profile photo sync is off: %d stored photo removed."
|
||||||
|
msgid_plural "Profile photo sync is off: %d stored photos removed."
|
||||||
|
msgstr[0] "Profilbild-Sync ist aus: %d gespeichertes Profilbild entfernt."
|
||||||
|
msgstr[1] "Profilbild-Sync ist aus: %d gespeicherte Profilbilder entfernt."
|
||||||
|
|
||||||
|
#: includes/class-m365-login-sync.php:1549 includes/class-m365-login-sync.php:1682
|
||||||
msgid "Microsoft 365"
|
msgid "Microsoft 365"
|
||||||
msgstr "Microsoft 365"
|
msgstr "Microsoft 365"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1451
|
#: includes/class-m365-login-sync.php:1567
|
||||||
msgid "Deactivated"
|
msgid "Deactivated"
|
||||||
msgstr "Deaktiviert"
|
msgstr "Deaktiviert"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1454
|
#: includes/class-m365-login-sync.php:1570
|
||||||
msgid "Imported"
|
msgid "Imported"
|
||||||
msgstr "Importiert"
|
msgstr "Importiert"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1456
|
#: includes/class-m365-login-sync.php:1572
|
||||||
msgid "Linked"
|
msgid "Linked"
|
||||||
msgstr "Verknüpft"
|
msgstr "Verknüpft"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1484
|
#: includes/class-m365-login-sync.php:1600
|
||||||
msgid "Reactivate"
|
msgid "Reactivate"
|
||||||
msgstr "Reaktivieren"
|
msgstr "Reaktivieren"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1484
|
#: includes/class-m365-login-sync.php:1600
|
||||||
msgid "Deactivate"
|
msgid "Deactivate"
|
||||||
msgstr "Deaktivieren"
|
msgstr "Deaktivieren"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1517
|
#: includes/class-m365-login-sync.php:1633
|
||||||
msgid "The account has been deactivated and signed out everywhere."
|
msgid "The account has been deactivated and signed out everywhere."
|
||||||
msgstr "Das Konto wurde deaktiviert und überall abgemeldet."
|
msgstr "Das Konto wurde deaktiviert und überall abgemeldet."
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1518
|
#: includes/class-m365-login-sync.php:1634
|
||||||
msgid "The account has been reactivated."
|
msgid "The account has been reactivated."
|
||||||
msgstr "Das Konto wurde reaktiviert."
|
msgstr "Das Konto wurde reaktiviert."
|
||||||
|
|
||||||
#. translators: 1: date, 2: reason
|
#. translators: 1: date, 2: reason
|
||||||
#: includes/class-m365-login-sync.php:1542
|
#: includes/class-m365-login-sync.php:1658
|
||||||
msgid "Deactivated since %1$s (%2$s)"
|
msgid "Deactivated since %1$s (%2$s)"
|
||||||
msgstr "Deaktiviert seit %1$s (%2$s)"
|
msgstr "Deaktiviert seit %1$s (%2$s)"
|
||||||
|
|
||||||
#. translators: 1: date, 2: reason
|
#. translators: 1: date, 2: reason
|
||||||
#: includes/class-m365-login-sync.php:1544
|
#: includes/class-m365-login-sync.php:1660
|
||||||
msgid "manually"
|
msgid "manually"
|
||||||
msgstr "manuell"
|
msgstr "manuell"
|
||||||
|
|
||||||
#. translators: 1: date, 2: reason
|
#. translators: 1: date, 2: reason
|
||||||
#: includes/class-m365-login-sync.php:1546
|
#: includes/class-m365-login-sync.php:1662
|
||||||
msgid "Status"
|
msgid "Status"
|
||||||
msgstr "Status"
|
msgstr "Status"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1549
|
#: includes/class-m365-login-sync.php:1665
|
||||||
msgid "Object ID"
|
msgid "Object ID"
|
||||||
msgstr "Objekt-ID"
|
msgstr "Objekt-ID"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1553
|
#: includes/class-m365-login-sync.php:1669
|
||||||
msgid "Last sync"
|
msgid "Last sync"
|
||||||
msgstr "Letzter Sync"
|
msgstr "Letzter Sync"
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1575
|
#: includes/class-m365-login-sync.php:1691
|
||||||
msgid "These values are managed by the Microsoft 365 user sync and overwritten on the next run."
|
msgid "These values are managed by the Microsoft 365 user sync and overwritten on the next run."
|
||||||
msgstr "Diese Werte verwaltet der Microsoft-365-Benutzer-Sync; sie werden beim nächsten Lauf überschrieben."
|
msgstr "Diese Werte verwaltet der Microsoft-365-Benutzer-Sync; sie werden beim nächsten Lauf überschrieben."
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ msgstr ""
|
||||||
msgid "Move up"
|
msgid "Move up"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-admin.php:261 includes/class-m365-login-admin.php:300 includes/class-m365-login-admin.php:326 includes/class-m365-login-admin.php:359 includes/class-m365-login-admin.php:514 includes/class-m365-login-sync.php:1495
|
#: includes/class-m365-login-admin.php:261 includes/class-m365-login-admin.php:300 includes/class-m365-login-admin.php:326 includes/class-m365-login-admin.php:359 includes/class-m365-login-admin.php:514 includes/class-m365-login-sync.php:1611
|
||||||
msgid "You are not allowed to do this."
|
msgid "You are not allowed to do this."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
@ -426,7 +426,7 @@ msgid "Selected Microsoft 365 attributes are copied into the WordPress profile o
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-admin.php:643
|
#: includes/class-m365-login-admin.php:643
|
||||||
msgid "Profile photos are stored in wp-content/uploads/m365-login-avatars/ and replace the Gravatar. They are checked about once a day per user."
|
msgid "Profile photos are stored in wp-content/uploads/m365-login-avatars/ and replace the Gravatar. They are compared on every run: changed photos are downloaded again, photos deleted in Microsoft 365 are deleted in WordPress too. Fields and photos you deselect here are removed from the profiles on the next run (first and last name and display name stay)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-admin.php:647
|
#: includes/class-m365-login-admin.php:647
|
||||||
|
|
@ -1117,7 +1117,7 @@ msgstr ""
|
||||||
msgid "Too many sign-in attempts from your connection. Please wait a few minutes and try again."
|
msgid "Too many sign-in attempts from your connection. Please wait a few minutes and try again."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-auth.php:864 includes/class-m365-login-sync.php:1404
|
#: includes/class-m365-login-auth.php:864 includes/class-m365-login-sync.php:1520
|
||||||
msgid "This account has been deactivated."
|
msgid "This account has been deactivated."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
@ -1173,15 +1173,15 @@ msgstr ""
|
||||||
msgid "The certificate has already expired."
|
msgid "The certificate has already expired."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-graph.php:375
|
#: includes/class-m365-login-graph.php:434
|
||||||
msgid "Group"
|
msgid "Group"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-graph.php:377
|
#: includes/class-m365-login-graph.php:436
|
||||||
msgid "Security group"
|
msgid "Security group"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-graph.php:379
|
#: includes/class-m365-login-graph.php:438
|
||||||
msgid "Microsoft 365 group"
|
msgid "Microsoft 365 group"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
@ -1233,293 +1233,312 @@ msgstr ""
|
||||||
msgid "User sync: \"Delete\" needs a user who receives the posts of deleted accounts. Until one is selected, accounts are deactivated instead."
|
msgid "User sync: \"Delete\" needs a user who receives the posts of deleted accounts. Until one is selected, accounts are deactivated instead."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:109
|
#: includes/class-m365-login-sync.php:110
|
||||||
msgid "Display name"
|
msgid "Display name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:113
|
#: includes/class-m365-login-sync.php:114
|
||||||
msgid "First name"
|
msgid "First name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:117
|
#: includes/class-m365-login-sync.php:118
|
||||||
msgid "Last name"
|
msgid "Last name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:121
|
#: includes/class-m365-login-sync.php:122
|
||||||
msgid "Profile photo (used as avatar)"
|
msgid "Profile photo (used as avatar)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:125
|
#: includes/class-m365-login-sync.php:126
|
||||||
msgid "Job title"
|
msgid "Job title"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:129
|
#: includes/class-m365-login-sync.php:130
|
||||||
msgid "Department"
|
msgid "Department"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:133
|
#: includes/class-m365-login-sync.php:134
|
||||||
msgid "Company"
|
msgid "Company"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:137
|
#: includes/class-m365-login-sync.php:138
|
||||||
msgid "Office"
|
msgid "Office"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:141
|
#: includes/class-m365-login-sync.php:142
|
||||||
msgid "Employee ID"
|
msgid "Employee ID"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:145
|
#: includes/class-m365-login-sync.php:146
|
||||||
msgid "Business phone"
|
msgid "Business phone"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:149
|
#: includes/class-m365-login-sync.php:150
|
||||||
msgid "Mobile phone"
|
msgid "Mobile phone"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:153
|
#: includes/class-m365-login-sync.php:154
|
||||||
msgid "Street address"
|
msgid "Street address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:157
|
#: includes/class-m365-login-sync.php:158
|
||||||
msgid "Postal code"
|
msgid "Postal code"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:161
|
#: includes/class-m365-login-sync.php:162
|
||||||
msgid "City"
|
msgid "City"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:165
|
#: includes/class-m365-login-sync.php:166
|
||||||
msgid "State / province"
|
msgid "State / province"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:169
|
#: includes/class-m365-login-sync.php:170
|
||||||
msgid "Country"
|
msgid "Country"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:173
|
#: includes/class-m365-login-sync.php:174
|
||||||
msgid "Language (sets the admin language if installed)"
|
msgid "Language (sets the admin language if installed)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:308
|
#: includes/class-m365-login-sync.php:309
|
||||||
msgid "Another sync is still running. Please try again in a few minutes."
|
msgid "Another sync is still running. Please try again in a few minutes."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:365
|
#: includes/class-m365-login-sync.php:366
|
||||||
msgid "The connection to Microsoft Entra ID is not configured yet."
|
msgid "The connection to Microsoft Entra ID is not configured yet."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:369
|
#: includes/class-m365-login-sync.php:370
|
||||||
msgid "The user sync needs a pinned tenant ID (GUID) on the Connection tab."
|
msgid "The user sync needs a pinned tenant ID (GUID) on the Connection tab."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:373
|
#: includes/class-m365-login-sync.php:374
|
||||||
msgid "The default role does not exist. Please check the sync settings."
|
msgid "The default role does not exist. Please check the sync settings."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: %d: number of users
|
#. translators: %d: number of users
|
||||||
#: includes/class-m365-login-sync.php:385
|
#: includes/class-m365-login-sync.php:386
|
||||||
msgid "%d user read from Microsoft 365."
|
msgid "%d user read from Microsoft 365."
|
||||||
msgid_plural "%d users read from Microsoft 365."
|
msgid_plural "%d users read from Microsoft 365."
|
||||||
msgstr[0] ""
|
msgstr[0] ""
|
||||||
msgstr[1] ""
|
msgstr[1] ""
|
||||||
|
|
||||||
#. translators: 1: number of accounts, 2: limit
|
#. translators: 1: number of accounts, 2: limit
|
||||||
#: includes/class-m365-login-sync.php:435
|
#: includes/class-m365-login-sync.php:443
|
||||||
msgid "Safety stop: %1$d accounts would be deactivated or deleted, more than the limit of %2$d per run. No account was deactivated or deleted. Check the sync groups and the tenant, then run the sync again (the limit can be changed with the m365_login_sync_deprovision_limit filter)."
|
msgid "Safety stop: %1$d accounts would be deactivated or deleted, more than the limit of %2$d per run. No account was deactivated or deleted. Check the sync groups and the tenant, then run the sync again (the limit can be changed with the m365_login_sync_deprovision_limit filter)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: %s: user principal name
|
#. translators: %s: user principal name
|
||||||
#: includes/class-m365-login-sync.php:559
|
#: includes/class-m365-login-sync.php:567
|
||||||
msgid "%s: no usable e-mail address, skipped."
|
msgid "%s: no usable e-mail address, skipped."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %s: e-mail address
|
||||||
#: includes/class-m365-login-sync.php:566
|
#: includes/class-m365-login-sync.php:574
|
||||||
msgid "%s: e-mail domain is not on the allow-list, skipped."
|
msgid "%s: e-mail domain is not on the allow-list, skipped."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %s: e-mail address
|
||||||
#: includes/class-m365-login-sync.php:578
|
#: includes/class-m365-login-sync.php:586
|
||||||
msgid "%s: the WordPress account with this e-mail address is linked to a different Microsoft account, skipped."
|
msgid "%s: the WordPress account with this e-mail address is linked to a different Microsoft account, skipped."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %s: e-mail address
|
||||||
#: includes/class-m365-login-sync.php:582
|
#: includes/class-m365-login-sync.php:590
|
||||||
msgid "%s: existing account linked."
|
msgid "%s: existing account linked."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:596 includes/class-m365-login-sync.php:931 includes/class-m365-login-sync.php:1536
|
#: includes/class-m365-login-sync.php:604 includes/class-m365-login-sync.php:955 includes/class-m365-login-sync.php:1652
|
||||||
msgid "disabled in Microsoft 365"
|
msgid "disabled in Microsoft 365"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %s: e-mail address
|
||||||
#: includes/class-m365-login-sync.php:607
|
#: includes/class-m365-login-sync.php:615
|
||||||
msgid "%s: added to this site."
|
msgid "%s: added to this site."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %s: e-mail address
|
||||||
#: includes/class-m365-login-sync.php:616
|
#: includes/class-m365-login-sync.php:624
|
||||||
msgid "%s: reactivated (active in Microsoft 365 again)."
|
msgid "%s: reactivated (active in Microsoft 365 again)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: 1: e-mail address, 2: list of changed fields
|
#. translators: 1: e-mail address, 2: list of changed fields
|
||||||
#: includes/class-m365-login-sync.php:627
|
#: includes/class-m365-login-sync.php:635
|
||||||
msgid "%1$s: updated (%2$s)."
|
msgid "%1$s: updated (%2$s)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: 1: e-mail address, 2: role names
|
#. translators: 1: e-mail address, 2: role names
|
||||||
#: includes/class-m365-login-sync.php:653
|
#: includes/class-m365-login-sync.php:661
|
||||||
msgid "%1$s: account created (%2$s)."
|
msgid "%1$s: account created (%2$s)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: 1: e-mail address, 2: error message
|
#. translators: 1: e-mail address, 2: error message
|
||||||
#: includes/class-m365-login-sync.php:680
|
#: includes/class-m365-login-sync.php:688
|
||||||
msgid "%1$s: account could not be created: %2$s"
|
msgid "%1$s: account could not be created: %2$s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %s: e-mail address
|
||||||
#: includes/class-m365-login-sync.php:738
|
#: includes/class-m365-login-sync.php:746
|
||||||
msgid "%s: e-mail address is used by another WordPress account and was not changed."
|
msgid "%s: e-mail address is used by another WordPress account and was not changed."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %s: e-mail address
|
||||||
#: includes/class-m365-login-sync.php:741
|
#: includes/class-m365-login-sync.php:749
|
||||||
msgid "e-mail"
|
msgid "e-mail"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#. translators: %s: profile field
|
||||||
|
#: includes/class-m365-login-sync.php:799
|
||||||
|
msgid "%s removed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#. translators: 1: e-mail address, 2: error message
|
#. translators: 1: e-mail address, 2: error message
|
||||||
#: includes/class-m365-login-sync.php:785
|
#: includes/class-m365-login-sync.php:809
|
||||||
msgid "%1$s: profile could not be updated: %2$s"
|
msgid "%1$s: profile could not be updated: %2$s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: %s: role names
|
#. translators: %s: role names
|
||||||
#: includes/class-m365-login-sync.php:891
|
#: includes/class-m365-login-sync.php:915
|
||||||
msgid "roles: %s"
|
msgid "roles: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:926 includes/class-m365-login-sync.php:1537
|
#: includes/class-m365-login-sync.php:950 includes/class-m365-login-sync.php:1653
|
||||||
msgid "deleted in Microsoft 365"
|
msgid "deleted in Microsoft 365"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:934 includes/class-m365-login-sync.php:1538
|
#: includes/class-m365-login-sync.php:958 includes/class-m365-login-sync.php:1654
|
||||||
msgid "no longer a member of the sync groups"
|
msgid "no longer a member of the sync groups"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: 1: e-mail address, 2: reason
|
#. translators: 1: e-mail address, 2: reason
|
||||||
#: includes/class-m365-login-sync.php:954
|
#: includes/class-m365-login-sync.php:978
|
||||||
msgid "%1$s: %2$s, but the account is protected (administrator or your own account) and was not changed."
|
msgid "%1$s: %2$s, but the account is protected (administrator or your own account) and was not changed."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %s: e-mail address
|
||||||
#: includes/class-m365-login-sync.php:987
|
#: includes/class-m365-login-sync.php:1011
|
||||||
msgid "%s: no valid user to receive the content is selected, so the account is deactivated instead of deleted."
|
msgid "%s: no valid user to receive the content is selected, so the account is deactivated instead of deleted."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: 1: e-mail address, 2: reason
|
#. translators: 1: e-mail address, 2: reason
|
||||||
#: includes/class-m365-login-sync.php:996
|
#: includes/class-m365-login-sync.php:1020
|
||||||
msgid "%1$s: account deleted (%2$s)."
|
msgid "%1$s: account deleted (%2$s)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: 1: e-mail address, 2: reason
|
#. translators: 1: e-mail address, 2: reason
|
||||||
#: includes/class-m365-login-sync.php:1006
|
#: includes/class-m365-login-sync.php:1029
|
||||||
msgid "%1$s: account deactivated (%2$s)."
|
msgid "%1$s: account deactivated (%2$s)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1085
|
#: includes/class-m365-login-sync.php:1108
|
||||||
msgid "Microsoft Graph refused the request. Grant the application permissions \"User.Read.All\" and \"GroupMember.Read.All\" with admin consent in Entra ID."
|
msgid "Microsoft Graph refused the request. Grant the application permissions \"User.Read.All\" and \"GroupMember.Read.All\" with admin consent in Entra ID."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: %s: error message
|
#. translators: %s: error message
|
||||||
#: includes/class-m365-login-sync.php:1088
|
#: includes/class-m365-login-sync.php:1111
|
||||||
msgid "Microsoft Graph error: %s"
|
msgid "Microsoft Graph error: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1106
|
#: includes/class-m365-login-sync.php:1129
|
||||||
msgid "Log truncated."
|
msgid "Log truncated."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: 1: e-mail address, 2: error message
|
#. translators: 1: e-mail address, 2: error message
|
||||||
#: includes/class-m365-login-sync.php:1168
|
#: includes/class-m365-login-sync.php:1205
|
||||||
msgid "%1$s: profile photo could not be read: %2$s"
|
msgid "%1$s: profile photo could not be read: %2$s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %s: e-mail address
|
||||||
#: includes/class-m365-login-sync.php:1176
|
#: includes/class-m365-login-sync.php:1229 includes/class-m365-login-sync.php:1272
|
||||||
msgid "%s: profile photo removed."
|
msgid "%s: profile photo updated."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %s: e-mail address
|
||||||
#: includes/class-m365-login-sync.php:1192
|
#: includes/class-m365-login-sync.php:1248
|
||||||
msgid "%s: profile photo could not be downloaded."
|
msgid "%s: profile photo could not be downloaded."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %s: e-mail address
|
||||||
#: includes/class-m365-login-sync.php:1199
|
#: includes/class-m365-login-sync.php:1255
|
||||||
msgid "%s: profile photo is not a valid image or could not be saved."
|
msgid "%s: profile photo is not a valid image or could not be saved."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#. translators: %d: number of photos
|
||||||
|
#: includes/class-m365-login-sync.php:1278
|
||||||
|
msgid "%d changed profile photo will be downloaded in the next run (download limit per run reached)."
|
||||||
|
msgid_plural "%d changed profile photos will be downloaded in the next run (download limit per run reached)."
|
||||||
|
msgstr[0] ""
|
||||||
|
msgstr[1] ""
|
||||||
|
|
||||||
#. translators: %s: e-mail address
|
#. translators: %s: e-mail address
|
||||||
#: includes/class-m365-login-sync.php:1216
|
#: includes/class-m365-login-sync.php:1293
|
||||||
msgid "%s: profile photo updated."
|
msgid "%s: profile photo removed."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1433 includes/class-m365-login-sync.php:1566
|
#. translators: %d: number of photos
|
||||||
|
#: includes/class-m365-login-sync.php:1321
|
||||||
|
msgid "Profile photo sync is off: %d stored photo removed."
|
||||||
|
msgid_plural "Profile photo sync is off: %d stored photos removed."
|
||||||
|
msgstr[0] ""
|
||||||
|
msgstr[1] ""
|
||||||
|
|
||||||
|
#: includes/class-m365-login-sync.php:1549 includes/class-m365-login-sync.php:1682
|
||||||
msgid "Microsoft 365"
|
msgid "Microsoft 365"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1451
|
#: includes/class-m365-login-sync.php:1567
|
||||||
msgid "Deactivated"
|
msgid "Deactivated"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1454
|
#: includes/class-m365-login-sync.php:1570
|
||||||
msgid "Imported"
|
msgid "Imported"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1456
|
#: includes/class-m365-login-sync.php:1572
|
||||||
msgid "Linked"
|
msgid "Linked"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1484
|
#: includes/class-m365-login-sync.php:1600
|
||||||
msgid "Reactivate"
|
msgid "Reactivate"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1484
|
#: includes/class-m365-login-sync.php:1600
|
||||||
msgid "Deactivate"
|
msgid "Deactivate"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1517
|
#: includes/class-m365-login-sync.php:1633
|
||||||
msgid "The account has been deactivated and signed out everywhere."
|
msgid "The account has been deactivated and signed out everywhere."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1518
|
#: includes/class-m365-login-sync.php:1634
|
||||||
msgid "The account has been reactivated."
|
msgid "The account has been reactivated."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: 1: date, 2: reason
|
#. translators: 1: date, 2: reason
|
||||||
#: includes/class-m365-login-sync.php:1542
|
#: includes/class-m365-login-sync.php:1658
|
||||||
msgid "Deactivated since %1$s (%2$s)"
|
msgid "Deactivated since %1$s (%2$s)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: 1: date, 2: reason
|
#. translators: 1: date, 2: reason
|
||||||
#: includes/class-m365-login-sync.php:1544
|
#: includes/class-m365-login-sync.php:1660
|
||||||
msgid "manually"
|
msgid "manually"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. translators: 1: date, 2: reason
|
#. translators: 1: date, 2: reason
|
||||||
#: includes/class-m365-login-sync.php:1546
|
#: includes/class-m365-login-sync.php:1662
|
||||||
msgid "Status"
|
msgid "Status"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1549
|
#: includes/class-m365-login-sync.php:1665
|
||||||
msgid "Object ID"
|
msgid "Object ID"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1553
|
#: includes/class-m365-login-sync.php:1669
|
||||||
msgid "Last sync"
|
msgid "Last sync"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: includes/class-m365-login-sync.php:1575
|
#: includes/class-m365-login-sync.php:1691
|
||||||
msgid "These values are managed by the Microsoft 365 user sync and overwritten on the next run."
|
msgid "These values are managed by the Microsoft 365 user sync and overwritten on the next run."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ When the optional **group restriction** or the optional **user sync** is used, t
|
||||||
* `/groups` – only when an administrator searches for groups in the settings screen. The typed search text is sent.
|
* `/groups` – only when an administrator searches for groups in the settings screen. The typed search text is sent.
|
||||||
* `/users/{id}/checkMemberGroups` – during sign-in when the ID token carries no usable `groups` claim. The user's Microsoft object ID and the configured group IDs are sent; Microsoft returns which of those groups the user belongs to.
|
* `/users/{id}/checkMemberGroups` – during sign-in when the ID token carries no usable `groups` claim. The user's Microsoft object ID and the configured group IDs are sent; Microsoft returns which of those groups the user belongs to.
|
||||||
* `/users`, `/groups/{id}/transitiveMembers`, `/users/{id}` – only while the user sync runs (manually, on the configured schedule or via WP-CLI). The configured group IDs and the object IDs of linked accounts are sent; Microsoft returns the users with their account status and the profile attributes selected in the settings.
|
* `/users`, `/groups/{id}/transitiveMembers`, `/users/{id}` – only while the user sync runs (manually, on the configured schedule or via WP-CLI). The configured group IDs and the object IDs of linked accounts are sent; Microsoft returns the users with their account status and the profile attributes selected in the settings.
|
||||||
* `/users/{id}/photos/240x240`, `/users/{id}/photo` – only while the user sync runs and "Profile photo" is selected. Returns the user's profile photo.
|
* `/$batch` with `/users/{id}/photo`, and `/users/{id}/photos/240x240`, `/users/{id}/photo` – only while the user sync runs and "Profile photo" is selected. Returns the version and, when it changed, the image of the user's profile photo.
|
||||||
|
|
||||||
For sign-in the plugin receives the user's e-mail address / user principal name, display name and Microsoft object ID and uses them solely to find the matching WordPress account. The user sync stores the object ID, the account status and the attributes selected by the administrator (for example name, job title, department, phone numbers, profile photo) in the WordPress user profile; profile photos are saved in `wp-content/uploads/m365-login-avatars/` and are shown publicly wherever WordPress displays avatars.
|
For sign-in the plugin receives the user's e-mail address / user principal name, display name and Microsoft object ID and uses them solely to find the matching WordPress account. The user sync stores the object ID, the account status and the attributes selected by the administrator (for example name, job title, department, phone numbers, profile photo) in the WordPress user profile; profile photos are saved in `wp-content/uploads/m365-login-avatars/` and are shown publicly wherever WordPress displays avatars.
|
||||||
|
|
||||||
|
|
@ -149,6 +149,7 @@ The settings, cached data, the sync report and schedule, stored profile photos a
|
||||||
|
|
||||||
= 1.1.0 =
|
= 1.1.0 =
|
||||||
* New: user sync – import Microsoft 365 users (whole tenant or selected groups) with a default role and group → role mapping, selectable profile attributes and profile photos as avatars.
|
* New: user sync – import Microsoft 365 users (whole tenant or selected groups) with a default role and group → role mapping, selectable profile attributes and profile photos as avatars.
|
||||||
|
* New: profile fields and photos follow Microsoft 365 on every run – changed photos are replaced, deleted photos and cleared or deselected fields are removed.
|
||||||
* New: deactivate or delete WordPress accounts whose Microsoft 365 account was disabled or deleted; automatic reactivation; dry run, safety stop and protected administrators.
|
* New: deactivate or delete WordPress accounts whose Microsoft 365 account was disabled or deleted; automatic reactivation; dry run, safety stop and protected administrators.
|
||||||
* New: "Microsoft 365" column, deactivate/reactivate row actions and a read-only Microsoft 365 section on the profile screen.
|
* New: "Microsoft 365" column, deactivate/reactivate row actions and a read-only Microsoft 365 section on the profile screen.
|
||||||
* New: `wp m365-login sync [--dry-run]` WP-CLI command and scheduled sync via WP-Cron.
|
* New: `wp m365-login sync [--dry-run]` WP-CLI command and scheduled sync via WP-Cron.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue