2424use MikoPBX \Common \Models \Users ;
2525use MikoPBX \Common \Providers \PBXCoreRESTClientProvider ;
2626use MikoPBX \Modules \Logger ;
27- use MikoPBX \PBXCoreREST \Lib \Extensions \DataStructure ;
2827use Modules \ModuleLdapSync \Lib \Workers \WorkerLdapSync ;
2928use Modules \ModuleLdapSync \Models \ADUsers ;
3029use Modules \ModuleLdapSync \Models \LdapServers ;
@@ -355,13 +354,13 @@ public static function getUserOnMikoPBX(string $userId): array
355354 }
356355
357356 /**
358- * Creates or updates a user using provided data.
357+ * Creates or updates a user using provided data via REST API v3 .
359358 *
360359 * @param array $userDataFromLdap - User data to be created or updated.
361360 * @param ?string $currentUserId The current user id.
362361 * @return AnswerStructure
363362 */
364- public static function createUpdateUser (array $ userDataFromLdap , string $ currentUserId = null ): AnswerStructure
363+ public static function createUpdateUser (array $ userDataFromLdap , ? string $ currentUserId = null ): AnswerStructure
365364 {
366365 $ pbxUserData = self ::findUserInMikoPBX ($ userDataFromLdap , $ currentUserId );
367366
@@ -374,91 +373,134 @@ public static function createUpdateUser(array $userDataFromLdap, string $current
374373 return $ result ;
375374 }
376375
377- // Get user data from the API
378- $ di =MikoPBXVersion::getDefaultDi ();
379- $ restAnswer = $ di ->get (PBXCoreRESTClientProvider::SERVICE_NAME , [
380- '/pbxcore/api/extensions/getRecord ' ,
381- PBXCoreRESTClientProvider::HTTP_METHOD_GET ,
382- ['id ' => $ pbxUserData ['extension_id ' ] ?? '' ]
383- ]);
376+ $ di = MikoPBXVersion::getDefaultDi ();
377+ $ isNewEmployee = empty ($ pbxUserData ['user_id ' ]);
378+
379+ // Get existing employee data or defaults for new employee
380+ if ($ isNewEmployee ) {
381+ // Get default template for new employee
382+ $ restAnswer = $ di ->get (PBXCoreRESTClientProvider::SERVICE_NAME , [
383+ '/pbxcore/api/v3/employees:getDefault ' ,
384+ PBXCoreRESTClientProvider::HTTP_METHOD_GET
385+ ]);
386+ } else {
387+ // Get existing employee data by user_id
388+ $ restAnswer = $ di ->get (PBXCoreRESTClientProvider::SERVICE_NAME , [
389+ '/pbxcore/api/v3/employees/ ' . $ pbxUserData ['user_id ' ],
390+ PBXCoreRESTClientProvider::HTTP_METHOD_GET
391+ ]);
392+ }
393+
384394 if (!$ restAnswer ->success ) {
385395 return new AnswerStructure ($ restAnswer );
386396 }
387397
388- // Create a new data structure for user data
389- $ dataStructure = new DataStructure ($ restAnswer ->data );
398+ $ employeeData = $ restAnswer ->data ;
390399
391400 // Check if provided phone number is available
392- $ number = $ userDataFromLdap [Constants::USER_EXTENSION_ATTR ];
393- if (!empty ($ number ) && $ number !== $ dataStructure -> number ) {
401+ $ number = $ userDataFromLdap [Constants::USER_EXTENSION_ATTR ] ?? null ;
402+ if (!empty ($ number ) && $ number !== ( $ employeeData [ ' number ' ] ?? '' ) ) {
394403 $ restAnswer = $ di ->get (PBXCoreRESTClientProvider::SERVICE_NAME , [
395- '/pbxcore/api/extensions/available ' ,
396- PBXCoreRESTClientProvider::HTTP_METHOD_GET ,
397- ['number ' => $ number ]
404+ '/pbxcore/api/v3/extensions:available ' ,
405+ PBXCoreRESTClientProvider::HTTP_METHOD_POST ,
406+ ['number ' => $ number ],
407+ ['Content-Type ' => 'application/json ' ]
398408 ]);
399- if ($ restAnswer ->success || $ restAnswer ->data ['userId ' ] == $ pbxUserData ['user_id ' ]) {
400- $ dataStructure -> number = $ number ;
409+ if ($ restAnswer ->success || ( $ restAnswer ->data ['userId ' ] ?? null ) == $ pbxUserData ['user_id ' ]) {
410+ $ employeeData [ ' number ' ] = $ number ;
401411 }
402412 }
403413
404414 // Check if provided mobile number is available
405- $ mobileFromDomain = $ userDataFromLdap [Constants::USER_MOBILE_ATTR ];
406- if (!empty ($ mobileFromDomain ) && $ mobileFromDomain !== $ dataStructure -> mobile_number ) {
415+ $ mobileFromDomain = $ userDataFromLdap [Constants::USER_MOBILE_ATTR ] ?? null ;
416+ if (!empty ($ mobileFromDomain ) && $ mobileFromDomain !== ( $ employeeData [ ' mobile_number ' ] ?? '' ) ) {
407417 $ restAnswer = $ di ->get (PBXCoreRESTClientProvider::SERVICE_NAME , [
408- '/pbxcore/api/extensions/available ' ,
409- PBXCoreRESTClientProvider::HTTP_METHOD_GET ,
410- ['number ' => $ mobileFromDomain ]
418+ '/pbxcore/api/v3/extensions:available ' ,
419+ PBXCoreRESTClientProvider::HTTP_METHOD_POST ,
420+ ['number ' => $ mobileFromDomain ],
421+ ['Content-Type ' => 'application/json ' ]
411422 ]);
412- if ($ restAnswer ->success || $ restAnswer ->data ['userId ' ] == $ pbxUserData ['user_id ' ]) {
423+ if ($ restAnswer ->success || ( $ restAnswer ->data ['userId ' ] ?? null ) == $ pbxUserData ['user_id ' ]) {
413424 // Update mobile number and forwarding settings
414- $ oldMobileNumber = $ dataStructure -> mobile_number ;
415- $ dataStructure -> mobile_number = $ mobileFromDomain ;
416- $ dataStructure -> mobile_dialstring = $ mobileFromDomain ;
425+ $ oldMobileNumber = $ employeeData [ ' mobile_number ' ] ?? '' ;
426+ $ employeeData [ ' mobile_number ' ] = $ mobileFromDomain ;
427+ $ employeeData [ ' mobile_dialstring ' ] = $ mobileFromDomain ;
417428
418- if ($ oldMobileNumber === $ dataStructure -> fwd_forwardingonunavailable ) {
419- $ dataStructure -> fwd_forwardingonunavailable = $ mobileFromDomain ;
429+ if ($ oldMobileNumber === ( $ employeeData [ ' fwd_forwardingonunavailable ' ] ?? '' ) ) {
430+ $ employeeData [ ' fwd_forwardingonunavailable ' ] = $ mobileFromDomain ;
420431 }
421- if ($ oldMobileNumber === $ dataStructure -> fwd_forwarding ) {
422- $ dataStructure -> fwd_forwarding = $ mobileFromDomain ;
432+ if ($ oldMobileNumber === ( $ employeeData [ ' fwd_forwarding ' ] ?? '' ) ) {
433+ $ employeeData [ ' fwd_forwarding ' ] = $ mobileFromDomain ;
423434 }
424- if ($ oldMobileNumber === $ dataStructure -> fwd_forwardingonbusy ) {
425- $ dataStructure -> fwd_forwardingonbusy = $ mobileFromDomain ;
435+ if ($ oldMobileNumber === ( $ employeeData [ ' fwd_forwardingonbusy ' ] ?? '' ) ) {
436+ $ employeeData [ ' fwd_forwardingonbusy ' ] = $ mobileFromDomain ;
426437 }
427438 }
428439 }
429440
430441 // Check if provided email is available
431- $ email = $ userDataFromLdap [Constants::USER_EMAIL_ATTR ]?? null ;
432- if (!empty ($ email ) && $ email !== $ dataStructure -> user_email ) {
442+ $ email = $ userDataFromLdap [Constants::USER_EMAIL_ATTR ] ?? null ;
443+ if (!empty ($ email ) && $ email !== ( $ employeeData [ ' user_email ' ] ?? '' ) ) {
433444 $ restAnswer = $ di ->get (PBXCoreRESTClientProvider::SERVICE_NAME , [
434- '/pbxcore/api/users/ available ' ,
445+ '/pbxcore/api/v3/users: available ' ,
435446 PBXCoreRESTClientProvider::HTTP_METHOD_GET ,
436447 ['email ' => $ email ]
437448 ]);
438- if ($ restAnswer ->success || $ restAnswer ->data ['userId ' ] == $ pbxUserData ['user_id ' ]) {
439- $ dataStructure -> user_email = $ email ;
449+ if ($ restAnswer ->success || ( $ restAnswer ->data ['userId ' ] ?? null ) == $ pbxUserData ['user_id ' ]) {
450+ $ employeeData [ ' user_email ' ] = $ email ;
440451 }
441452 }
442453
443- // Check provided sip password
444- $ sipPassword = $ userDataFromLdap [Constants::USER_PASSWORD_ATTR ] ?? $ dataStructure -> sip_secret ;
445- if (!empty ($ sipPassword ) && $ sipPassword != $ dataStructure -> sip_secret ) {
446- $ dataStructure -> sip_secret = $ sipPassword ;
454+ // Update SIP password if provided
455+ $ sipPassword = $ userDataFromLdap [Constants::USER_PASSWORD_ATTR ] ?? null ;
456+ if (!empty ($ sipPassword ) && $ sipPassword !== ( $ employeeData [ ' sip_secret ' ] ?? '' ) ) {
457+ $ employeeData [ ' sip_secret ' ] = $ sipPassword ;
447458 }
448459
449- $ dataStructure ->user_username = $ userDataFromLdap [Constants::USER_NAME_ATTR ] ?? $ dataStructure ->user_username ;
450-
451- $ dataStructure ->user_avatar = $ userDataFromLdap [Constants::USER_AVATAR_ATTR ] ?? $ dataStructure ->user_avatar ;
460+ // Update username
461+ if (!empty ($ userDataFromLdap [Constants::USER_NAME_ATTR ])) {
462+ $ employeeData ['user_username ' ] = $ userDataFromLdap [Constants::USER_NAME_ATTR ];
463+ }
452464
453- $ dataStructure ->sip_transport = trim ($ dataStructure ->sip_transport );
465+ // Update avatar
466+ if (!empty ($ userDataFromLdap [Constants::USER_AVATAR_ATTR ])) {
467+ $ employeeData ['user_avatar ' ] = $ userDataFromLdap [Constants::USER_AVATAR_ATTR ];
468+ }
454469
470+ // Trim transport value
471+ if (isset ($ employeeData ['sip_transport ' ])) {
472+ $ employeeData ['sip_transport ' ] = trim ($ employeeData ['sip_transport ' ]);
473+ }
455474
456- // Save user data through the CORE API
457- $ restAnswer = $ di ->get (PBXCoreRESTClientProvider::SERVICE_NAME , [
458- '/pbxcore/api/extensions/saveRecord ' ,
459- PBXCoreRESTClientProvider::HTTP_METHOD_POST ,
460- $ dataStructure ->toArray ()
461- ]);
475+ // Remove read-only fields before saving
476+ unset(
477+ $ employeeData ['extensions_length ' ],
478+ $ employeeData ['sip_networkfilterid_represent ' ],
479+ $ employeeData ['fwd_forwarding_represent ' ],
480+ $ employeeData ['fwd_forwardingonbusy_represent ' ],
481+ $ employeeData ['fwd_forwardingonunavailable_represent ' ],
482+ $ employeeData ['represent ' ],
483+ $ employeeData ['search_index ' ]
484+ );
485+
486+ // Save employee data through the REST API v3
487+ if ($ isNewEmployee ) {
488+ // Create new employee
489+ $ restAnswer = $ di ->get (PBXCoreRESTClientProvider::SERVICE_NAME , [
490+ '/pbxcore/api/v3/employees ' ,
491+ PBXCoreRESTClientProvider::HTTP_METHOD_POST ,
492+ $ employeeData ,
493+ ['Content-Type ' => 'application/json ' ]
494+ ]);
495+ } else {
496+ // Update existing employee using PATCH (partial update)
497+ $ restAnswer = $ di ->get (PBXCoreRESTClientProvider::SERVICE_NAME , [
498+ '/pbxcore/api/v3/employees/ ' . $ pbxUserData ['user_id ' ],
499+ PBXCoreRESTClientProvider::HTTP_METHOD_PATCH ,
500+ $ employeeData ,
501+ ['Content-Type ' => 'application/json ' ]
502+ ]);
503+ }
462504
463505 return new AnswerStructure ($ restAnswer );
464506 }
@@ -470,7 +512,7 @@ public static function createUpdateUser(array $userDataFromLdap, string $current
470512 * @param ?string $currentUserId The current user id.
471513 * @return array The user data if found, otherwise an empty array.
472514 */
473- public static function findUserInMikoPBX (array $ userDataFromLdap , string $ currentUserId = null ): array
515+ public static function findUserInMikoPBX (array $ userDataFromLdap , ? string $ currentUserId = null ): array
474516 {
475517 $ parameters = [
476518 'models ' => [
0 commit comments