2021-10-08 19:45:20 +02:00
< ? php
2021-10-10 20:57:23 +02:00
/**
2024-01-02 21:57:26 +01:00
* @ copyright Copyright ( C ) 2010 - 2024 , the Friendica project
2021-10-10 20:57:23 +02:00
*
* @ license GNU AGPL version 3 or any later version
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation , either version 3 of the
* License , or ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU Affero General Public License for more details .
*
* You should have received a copy of the GNU Affero General Public License
* along with this program . If not , see < https :// www . gnu . org / licenses />.
*
*/
2021-10-08 19:45:20 +02:00
2021-10-21 23:18:08 +02:00
namespace Friendica\Profile\ProfileField\Repository ;
2021-10-08 19:45:20 +02:00
2021-10-21 23:18:08 +02:00
use Friendica\BaseRepository ;
2021-10-08 19:45:20 +02:00
use Friendica\Database\Database ;
2021-10-10 20:39:35 +02:00
use Friendica\Profile\ProfileField\Exception\ProfileFieldNotFoundException ;
use Friendica\Profile\ProfileField\Exception\ProfileFieldPersistenceException ;
2021-10-17 15:32:50 +02:00
use Friendica\Profile\ProfileField\Exception\UnexpectedPermissionSetException ;
2021-10-08 19:45:20 +02:00
use Friendica\Profile\ProfileField\Factory ;
use Friendica\Profile\ProfileField\Entity ;
use Friendica\Profile\ProfileField\Collection ;
2021-10-21 23:18:08 +02:00
use Friendica\Security\PermissionSet\Repository\PermissionSet as PermissionSetRepository ;
2021-10-10 22:45:25 +02:00
use Friendica\Util\DateTimeFormat ;
2021-10-08 19:45:20 +02:00
use Psr\Log\LoggerInterface ;
2021-10-21 23:18:08 +02:00
class ProfileField extends BaseRepository
2021-10-08 19:45:20 +02:00
{
/** @var Factory\ProfileField */
protected $factory ;
protected static $table_name = 'profile_field' ;
2021-10-17 15:32:50 +02:00
protected static $view_name = 'profile_field-view' ;
2021-10-21 23:18:08 +02:00
/** @var PermissionSetRepository */
protected $permissionSetRepository ;
2021-10-08 20:01:09 +02:00
2021-10-21 23:18:08 +02:00
public function __construct ( Database $database , LoggerInterface $logger , Factory\ProfileField $factory , PermissionSetRepository $permissionSetRepository )
2021-10-08 19:45:20 +02:00
{
parent :: __construct ( $database , $logger , $factory );
2021-10-08 20:01:09 +02:00
2021-10-21 23:18:08 +02:00
$this -> permissionSetRepository = $permissionSetRepository ;
2021-10-08 19:45:20 +02:00
}
/**
* @ param array $condition
* @ param array $params
2021-10-17 15:32:50 +02:00
*
2021-10-08 19:45:20 +02:00
* @ return Entity\ProfileField
2021-10-17 15:32:50 +02:00
*
2021-10-10 20:39:35 +02:00
* @ throws ProfileFieldNotFoundException
2021-10-17 15:32:50 +02:00
* @ throws UnexpectedPermissionSetException
2021-10-08 19:45:20 +02:00
*/
private function selectOne ( array $condition , array $params = []) : Entity\ProfileField
{
2021-10-17 15:32:50 +02:00
$fields = $this -> db -> selectFirst ( static :: $view_name , [], $condition , $params );
if ( ! $this -> db -> isResult ( $fields )) {
throw new ProfileFieldNotFoundException ();
2021-10-10 20:39:35 +02:00
}
2021-10-17 15:32:50 +02:00
return $this -> factory -> createFromTableRow ( $fields );
2021-10-08 19:45:20 +02:00
}
2021-10-10 20:39:35 +02:00
/**
* @ param array $condition
* @ param array $params
*
* @ return Collection\ProfileFields
*
* @ throws ProfileFieldPersistenceException In case of underlying persistence exceptions
2021-10-17 15:32:50 +02:00
* @ throws UnexpectedPermissionSetException
2021-10-10 20:39:35 +02:00
*/
2021-10-08 19:45:20 +02:00
private function select ( array $condition , array $params = []) : Collection\ProfileFields
{
2021-10-17 15:32:50 +02:00
$rows = $this -> db -> selectToArray ( static :: $view_name , [], $condition , $params );
$Entities = new Collection\ProfileFields ();
foreach ( $rows as $fields ) {
$Entities [] = $this -> factory -> createFromTableRow ( $fields );
2021-10-10 20:39:35 +02:00
}
2021-10-17 15:32:50 +02:00
return $Entities ;
2021-10-10 20:39:35 +02:00
}
/**
* Converts a given ProfileField into a DB compatible row array
*
* @ param Entity\ProfileField $profileField
*
* @ return array
*/
protected function convertToTableRow ( Entity\ProfileField $profileField ) : array
{
return [
2021-10-10 22:45:25 +02:00
'uid' => $profileField -> uid ,
2021-10-10 20:39:35 +02:00
'label' => $profileField -> label ,
'value' => $profileField -> value ,
'order' => $profileField -> order ,
2021-10-10 22:45:25 +02:00
'created' => $profileField -> created -> format ( DateTimeFormat :: MYSQL ),
'edited' => $profileField -> edited -> format ( DateTimeFormat :: MYSQL ),
2021-10-17 15:32:50 +02:00
'psid' => $profileField -> permissionSet -> id
2021-10-10 20:39:35 +02:00
];
2021-10-08 19:45:20 +02:00
}
/**
* Returns all public available ProfileFields for a specific user
*
* @ param int $uid the user id
*
* @ return Collection\ProfileFields
2021-10-10 20:39:35 +02:00
*
* @ throws ProfileFieldPersistenceException In case of underlying persistence exceptions
2021-10-08 19:45:20 +02:00
*/
public function selectPublicFieldsByUserId ( int $uid ) : Collection\ProfileFields
{
2021-10-10 20:39:35 +02:00
try {
2021-10-21 23:18:08 +02:00
$publicPermissionSet = $this -> permissionSetRepository -> selectPublicForUser ( $uid );
2021-10-17 23:10:10 +02:00
2021-10-10 20:39:35 +02:00
return $this -> select ([
'uid' => $uid ,
2021-10-17 23:10:10 +02:00
'psid' => $publicPermissionSet -> id
2021-10-10 20:39:35 +02:00
]);
} catch ( \Exception $exception ) {
throw new ProfileFieldPersistenceException ( sprintf ( 'Cannot select public ProfileField for user "%d"' , $uid ), $exception );
}
2021-10-08 19:45:20 +02:00
}
2021-10-08 20:01:09 +02:00
/**
* @ param int $uid Field owner user Id
*
2021-10-10 20:39:35 +02:00
* @ throws ProfileFieldPersistenceException In case of underlying persistence exceptions
2021-10-08 20:01:09 +02:00
*/
public function selectByUserId ( int $uid ) : Collection\ProfileFields
{
2021-10-10 20:39:35 +02:00
try {
return $this -> select (
[ 'uid' => $uid ],
[ 'order' => [ 'order' ]]
);
} catch ( \Exception $exception ) {
throw new ProfileFieldPersistenceException ( sprintf ( 'Cannot select ProfileField for user "%d"' , $uid ), $exception );
}
2021-10-08 20:01:09 +02:00
}
/**
* Retrieve all custom profile field a given contact is able to access to , including public profile fields .
*
* @ param int $cid Private contact id , must be owned by $uid
* @ param int $uid Field owner user id
*
* @ throws \Exception
*/
public function selectByContactId ( int $cid , int $uid ) : Collection\ProfileFields
{
2021-10-21 23:18:08 +02:00
$permissionSets = $this -> permissionSetRepository -> selectByContactId ( $cid , $uid );
2021-10-08 20:01:09 +02:00
$permissionSetIds = $permissionSets -> column ( 'id' );
// Includes public custom fields
2021-10-21 23:18:08 +02:00
$permissionSetIds [] = $this -> permissionSetRepository -> selectPublicForUser ( $uid ) -> id ;
2021-10-08 20:01:09 +02:00
return $this -> select (
[ 'uid' => $uid , 'psid' => $permissionSetIds ],
[ 'order' => [ 'order' ]]
);
}
2021-10-10 20:39:35 +02:00
/**
* @ param int $id
*
* @ return Entity\ProfileField
*
* @ ProfileFieldNotFoundException In case there is no ProfileField found
*/
2021-10-17 15:32:50 +02:00
public function selectOneById ( int $id ) : Entity\ProfileField
2021-10-10 20:39:35 +02:00
{
try {
return $this -> selectOne ([ 'id' => $id ]);
} catch ( \Exception $exception ) {
throw new ProfileFieldNotFoundException ( sprintf ( 'Cannot find Profile "%s"' , $id ), $exception );
}
}
/**
2023-03-27 00:09:03 +02:00
* Deletes a whole collection of ProfileFields
2021-10-10 20:39:35 +02:00
*
* @ param Collection\ProfileFields $profileFields
*
* @ return bool
* @ throws ProfileFieldPersistenceException in case the persistence layer cannot delete the ProfileFields
*/
public function deleteCollection ( Collection\ProfileFields $profileFields ) : bool
{
try {
return $this -> db -> delete ( self :: $table_name , [ 'id' => $profileFields -> column ( 'id' )]);
} catch ( \Exception $exception ) {
throw new ProfileFieldPersistenceException ( 'Cannot delete ProfileFields' , $exception );
}
}
/**
* @ param Entity\ProfileField $profileField
*
* @ return Entity\ProfileField
* @ throws ProfileFieldPersistenceException in case the persistence layer cannot save the ProfileField
*/
public function save ( Entity\ProfileField $profileField ) : Entity\ProfileField
{
2021-10-17 23:10:10 +02:00
if ( $profileField -> permissionSet -> id === null ) {
throw new ProfileFieldPersistenceException ( 'PermissionSet needs to be saved first.' );
}
2021-10-10 20:39:35 +02:00
$fields = $this -> convertToTableRow ( $profileField );
try {
if ( $profileField -> id ) {
2021-10-10 22:45:25 +02:00
$this -> db -> update ( self :: $table_name , $fields , [ 'id' => $profileField -> id ]);
2021-10-10 20:39:35 +02:00
} else {
$this -> db -> insert ( self :: $table_name , $fields );
2021-10-17 15:32:50 +02:00
$profileField = $this -> selectOneById ( $this -> db -> lastInsertId ());
2021-10-10 20:39:35 +02:00
}
} catch ( \Exception $exception ) {
throw new ProfileFieldPersistenceException ( sprintf ( 'Cannot save ProfileField with id "%d" and label "%s"' , $profileField -> id , $profileField -> label ), $exception );
}
return $profileField ;
}
public function saveCollectionForUser ( int $uid , Collection\ProfileFields $profileFields ) : Collection\ProfileFields
{
$savedProfileFields = new Collection\ProfileFields ();
$profileFieldsOld = $this -> selectByUserId ( $uid );
// Prunes profile field whose label has been emptied
$labels = $profileFields -> column ( 'label' );
$prunedProfileFieldsOld = $profileFieldsOld -> filter ( function ( Entity\ProfileField $profileFieldOld ) use ( $labels ) {
return array_search ( $profileFieldOld -> label , $labels ) === false ;
});
$this -> deleteCollection ( $prunedProfileFieldsOld );
// Update the order based on the new Profile Field Collection
$order = 0 ;
2021-10-10 22:45:25 +02:00
$labelProfileFieldsOld = array_flip ( $profileFieldsOld -> column ( 'label' ));
2021-10-10 20:39:35 +02:00
foreach ( $profileFields as $profileField ) {
// Update existing field (preserve
if ( array_key_exists ( $profileField -> label , $labelProfileFieldsOld )) {
$profileFieldOldId = $labelProfileFieldsOld [ $profileField -> label ];
/** @var Entity\ProfileField $foundProfileFieldOld */
$foundProfileFieldOld = $profileFieldsOld [ $profileFieldOldId ];
$foundProfileFieldOld -> update (
$profileField -> value ,
$order ,
$profileField -> permissionSet
);
$savedProfileFields -> append ( $this -> save ( $foundProfileFieldOld ));
} else {
$profileField -> setOrder ( $order );
$savedProfileFields -> append ( $this -> save ( $profileField ));
}
$order ++ ;
}
return $savedProfileFields ;
}
2021-10-08 19:45:20 +02:00
}