2023-07-20 19:36:43 +00:00
< ? php
namespace Misuzu\Profile ;
use InvalidArgumentException ;
use RuntimeException ;
use Index\Data\IDbConnection ;
use Index\Data\IDbResult ;
use Misuzu\DbStatementCache ;
use Misuzu\Users\User ;
class ProfileFields {
private DbStatementCache $cache ;
public function __construct ( IDbConnection $dbConn ) {
$this -> cache = new DbStatementCache ( $dbConn );
}
public function getFields ( ? array $fieldValueInfos = null ) : array {
$hasFieldValueInfos = $fieldValueInfos !== null ;
if ( $hasFieldValueInfos && empty ( $fieldValueInfos ))
return [];
$query = 'SELECT field_id, field_order, field_key, field_title, field_regex FROM msz_profile_fields' ;
if ( $hasFieldValueInfos )
$query .= sprintf ( ' WHERE field_id IN (%s)' , msz_where_in_list ( $fieldValueInfos ));
$query .= ' ORDER BY field_order ASC' ;
$stmt = $this -> cache -> get ( $query );
$args = 0 ;
if ( $hasFieldValueInfos )
foreach ( $fieldValueInfos as $fieldValueInfo ) {
if ( ! ( $fieldValueInfo instanceof ProfileFieldValueInfo ))
throw new InvalidArgumentException ( 'All values in $fieldValueInfos must be of ProfileFieldValueInfo type.' );
$stmt -> addParameter ( ++ $args , $fieldValueInfo -> getFieldId ());
}
$stmt -> execute ();
$result = $stmt -> getResult ();
$fields = [];
while ( $result -> next ())
$fields [] = new ProfileFieldInfo ( $result );
return $fields ;
}
public function getField ( string $fieldId ) : ProfileFieldInfo {
$stmt = $this -> cache -> get ( 'SELECT field_id, field_order, field_key, field_title, field_regex FROM msz_profile_fields WHERE field_id = ?' );
$stmt -> addParameter ( 1 , $fieldId );
$stmt -> execute ();
$result = $stmt -> getResult ();
if ( ! $result -> next ())
throw new RuntimeException ( 'No field found with the provided field id.' );
return new ProfileFieldInfo ( $result );
}
public function getFieldFormats (
? array $fieldInfos = null ,
? array $fieldValueInfos = null
) : array {
$hasFieldInfos = $fieldInfos !== null ;
$hasFieldValueInfos = $fieldValueInfos !== null ;
if ( $hasFieldInfos && empty ( $fieldInfos ))
return [];
if ( $hasFieldValueInfos && empty ( $fieldValueInfos ))
return [];
$args = 0 ;
$query = 'SELECT format_id, field_id, format_regex, format_link, format_display FROM msz_profile_fields_formats' ;
if ( $hasFieldInfos ) {
++ $args ;
$query .= sprintf ( ' WHERE field_id IN (%s)' , msz_where_in_list ( $fieldInfos ));
}
if ( $hasFieldValueInfos )
$query .= sprintf ( ' %s format_id IN (%s)' ,
( ++ $args > 1 ? 'AND' : 'WHERE' ),
msz_where_in_list ( $fieldValueInfos )
);
$stmt = $this -> cache -> get ( $query );
$args = 0 ;
if ( $hasFieldInfos )
foreach ( $fieldInfos as $fieldInfo ) {
if ( ! ( $fieldInfo instanceof ProfileFieldInfo ))
throw new InvalidArgumentException ( 'All values in $fieldInfos must be of ProfileFieldInfo type.' );
$stmt -> addParameter ( ++ $args , $fieldInfo -> getId ());
}
if ( $hasFieldValueInfos )
foreach ( $fieldValueInfos as $fieldValueInfo ) {
if ( ! ( $fieldValueInfo instanceof ProfileFieldValueInfo ))
throw new InvalidArgumentException ( 'All values in $fieldValueInfos must be of ProfileFieldValueInfo type.' );
$stmt -> addParameter ( ++ $args , $fieldValueInfo -> getFormatId ());
}
$stmt -> execute ();
$result = $stmt -> getResult ();
$formats = [];
while ( $result -> next ())
$formats [] = new ProfileFieldFormatInfo ( $result );
return $formats ;
}
public function getFieldFormat ( string $formatId ) : ProfileFieldFormatInfo {
$stmt = $this -> cache -> get ( 'SELECT format_id, field_id, format_regex, format_link, format_display FROM msz_profile_fields_formats WHERE format_id = ?' );
$stmt -> addParameter ( 1 , $formatId );
$stmt -> execute ();
$result = $stmt -> getResult ();
if ( ! $result -> next ())
throw new RuntimeException ( 'No format found with the provided format id.' );
return new ProfileFieldFormatInfo ( $result );
}
public function selectFieldFormat (
ProfileFieldInfo | string $fieldInfo ,
string $value
) : ProfileFieldFormatInfo {
if ( $fieldInfo instanceof ProfileFieldInfo )
$fieldInfo = $fieldInfo -> getId ();
$stmt = $this -> cache -> get ( 'SELECT format_id, field_id, format_regex, format_link, format_display FROM msz_profile_fields_formats WHERE field_id = ? AND (format_regex IS NULL OR ? REGEXP format_regex) ORDER BY format_regex IS NULL ASC' );
$stmt -> addParameter ( 1 , $fieldInfo );
$stmt -> addParameter ( 2 , $value );
$stmt -> execute ();
$result = $stmt -> getResult ();
if ( ! $result -> next ())
throw new RuntimeException ( 'Could not determine an appropriate format for this field (missing default formatting)' );
return new ProfileFieldFormatInfo ( $result );
}
public function getFieldValues ( User | string $userInfo ) : array {
if ( $userInfo instanceof User )
$userInfo = $userInfo -> getId ();
// i don't really want to bother with the join for the ordering so i'll just do that somewhere in PHP for now
// will probably add the ability for people to order them in whatever way they want, as well as visibility controls
$stmt = $this -> cache -> get ( 'SELECT field_id, user_id, format_id, field_value FROM msz_profile_fields_values WHERE user_id = ?' );
$stmt -> addParameter ( 1 , $userInfo );
$stmt -> execute ();
$result = $stmt -> getResult ();
$values = [];
while ( $result -> next ())
$values [] = new ProfileFieldValueInfo ( $result );
return $values ;
}
public function getFieldValue (
ProfileFieldInfo | string $fieldInfo ,
User | string $userInfo
) : ProfileFieldValueInfo {
if ( $fieldInfo instanceof ProfileFieldInfo )
$fieldInfo = $fieldInfo -> getId ();
if ( $userInfo instanceof User )
$userInfo = $userInfo -> getId ();
$stmt = $this -> cache -> get ( 'SELECT field_id, user_id, format_id, field_value FROM msz_profile_fields_values WHERE field_id = ? AND user_id = ?' );
$stmt -> addParameter ( 1 , $fieldInfo );
$stmt -> addParameter ( 2 , $userInfo );
$stmt -> execute ();
$result = $stmt -> getResult ();
if ( ! $result -> next ())
throw new RuntimeException ( 'No value for this field and user combination found.' );
return new ProfileFieldValueInfo ( $result );
}
public function setFieldValues (
User | string $userInfo ,
ProfileFieldInfo | string | array $fieldInfos ,
string | array $values
) : void {
if ( empty ( $fieldInfos ))
return ;
if ( ! is_array ( $fieldInfos )) {
if ( is_array ( $values ))
throw new InvalidArgumentException ( 'If $fieldInfos is not an array, $values may not be either' );
$fieldInfos = [ $fieldInfos ];
$values = [ $values ];
} elseif ( ! is_array ( $values ))
throw new InvalidArgumentException ( 'If $fieldInfos is an array, $values must be as well.' );
$fieldsCount = count ( $fieldInfos );
if ( $fieldsCount !== count ( $values ))
throw new InvalidArgumentException ( '$fieldsInfos and $values have the same amount of values and be in the same order.' );
if ( $userInfo instanceof User )
$userInfo = $userInfo -> getId ();
$rows = [];
foreach ( $fieldInfos as $key => $fieldInfo ) {
if ( is_string ( $fieldInfo ))
2023-07-21 19:38:54 +00:00
$fieldInfo = $this -> getField ( $fieldInfo );
2023-07-20 19:36:43 +00:00
elseif ( ! ( $fieldInfo instanceof ProfileFieldInfo ))
throw new InvalidArgumentException ( 'Entries of $fieldInfos must either be field IDs or instances of ProfileFieldInfo.' );
$value = $fieldInfo -> matchValue ( $values [ $key ]);
if ( $value === false )
throw new InvalidArgumentException ( 'One of the values in $values is not correct formatted.' );
$rows [] = [
$fieldInfo -> getId (),
$this -> selectFieldFormat ( $fieldInfo , $value ) -> getId (),
$value ,
];
}
$args = 0 ;
$stmt = $this -> cache -> get (
'REPLACE INTO msz_profile_fields_values (field_id, user_id, format_id, field_value) VALUES '
. msz_where_in_list ( $rows , '(?, ?, ?, ?)' )
);
foreach ( $rows as $row ) {
$stmt -> addParameter ( ++ $args , $row [ 0 ]);
$stmt -> addParameter ( ++ $args , $userInfo );
$stmt -> addParameter ( ++ $args , $row [ 1 ]);
$stmt -> addParameter ( ++ $args , $row [ 2 ]);
}
$stmt -> execute ();
}
public function removeFieldValues (
User | string $userInfo ,
ProfileFieldInfo | string | array $fieldInfos
) : void {
if ( empty ( $fieldInfos ))
return ;
if ( $userInfo instanceof User )
$userInfo = $userInfo -> getId ();
if ( ! is_array ( $fieldInfos ))
$fieldInfos = [ $fieldInfos ];
foreach ( $fieldInfos as $key => $value ) {
if ( $value instanceof ProfileFieldInfo )
$fieldInfos [ $key ] = $value -> getId ();
elseif ( is_string ( $value ))
throw new InvalidArgumentException ( '$fieldInfos array may only contain string IDs or instances of ProfileFieldInfo' );
}
$args = 0 ;
$stmt = $this -> cache -> get ( sprintf (
'DELETE FROM msz_profile_fields_values WHERE user_id = ? AND field_id IN (%s)' ,
msz_where_in_list ( $fieldInfos )
));
$stmt -> addParameter ( ++ $args , $userInfo );
foreach ( $fieldInfos as $value )
$stmt -> addParameter ( ++ $args , $value );
$stmt -> execute ();
}
}