Version 5.0.13

This commit is contained in:
Neo committed 2025-12-19 19:04:57 -08:00
1 parent b89858b2ff
commit 5efe744c5f
1407 files changed
+69690 -30177

No files matched your search

@@ -41,9 +41,11 @@ use IPS\Helpers\Form\Text;
use IPS\Helpers\Form\Upload;
use IPS\Helpers\Form\YesNo;
use IPS\Helpers\Table\Content;
use IPS\Helpers\Table\Db as TableDb;
use IPS\Http\Url;
use IPS\Image;
use IPS\IPS;
use IPS\Lang;
use IPS\Log;
use IPS\Member;
use IPS\Member\Club;
@@ -51,6 +53,7 @@ use IPS\Member\Group;
use IPS\Member\ProfileStep;
use IPS\Output;
use IPS\Patterns\ActiveRecordIterator;
use IPS\Platform\Bridge;
use IPS\Request;
use IPS\Session;
use IPS\Settings;
@@ -64,6 +67,9 @@ use function defined;
use function in_array;
use function intval;
use function is_array;
use function is_numeric;
use function is_object;
use function is_string;
use const IPS\PHOTO_THUMBNAIL_SIZE;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
@@ -362,7 +368,7 @@ class profile extends Controller
);
/* Data Layer Stuff */
if ( Settings::i()->core_datalayer_enabled )
if ( DataLayer::enabled() )
{
try
{
@@ -620,7 +626,7 @@ class profile extends Controller
$baseUrl = $baseUrl->setQueryString( 'type', Request::i()->type );
}
if ( isset( Request::i()->page ) and Request::i()->page > 1 )
if ( isset( Request::i()->page ) and is_numeric( Request::i()->page ) and Request::i()->page > 1 )
{
$baseUrl = $baseUrl->setPage( 'page', Request::i()->page );
}
@@ -909,10 +915,11 @@ class profile extends Controller
/* Handle the submission */
if ( $values = $form->values() )
{
$this->_saveMember( $form, $values );
$dataLayerUpdates = [];
$this->_saveMember( $form, $values, $dataLayerUpdates );
/* Data Layer Stuff */
if ( Settings::i()->core_datalayer_enabled )
if ( DataLayer::enabled() )
{
try
{
@@ -927,6 +934,10 @@ class profile extends Controller
'profile_group_id' => $this->member->member_group_id ?: null,
'profile_id' => intval( $this->member->member_id ) ?: null,
'profile_name' => $this->member->name ?: null,
'updated_custom_fields' => $dataLayerUpdates['profile_fields'] ?? false,
'updated_profile_name' => false,
'updated_profile_photo' => false,
'updated_profile_coverphoto' => false,
);
DataLayer::i()->addEvent( 'social_update', $properties );
}
@@ -1067,9 +1078,10 @@ class profile extends Controller
*
* @param Form $form
* @param array $values
* @param array &$dataLayerUpdates=[] Optional: a reference to an array which will be populated with datalayer updates
* @return void
*/
protected function _saveMember( Form $form, array $values ) : void
protected function _saveMember( Form $form, array $values, array &$dataLayerUpdates=[] ) : void
{
if( isset( $values['bday'] ) )
{
@@ -1116,6 +1128,7 @@ class profile extends Controller
{
foreach ( $fields as $id => $field )
{
$originalValue = $profileFields[ 'field_' . $id ] ?? null;
if ( $field instanceof Upload )
{
$profileFields[ "field_{$id}" ] = (string) $values[ $field->name ];
@@ -1129,6 +1142,21 @@ class profile extends Controller
{
Field::load( $id )->claimAttachments( $this->member->member_id );
}
if ( $originalValue !== $profileFields[ "field_{$id}" ] )
{
$dataLayerUpdates['profile_fields'] = $dataLayerUpdates['profile_fields'] ?? [];
/* Note the char length on old and new is limited to prevent the datalayer JS object from getting too large. That should only really feasibly happen for editor fields anyway. */
$update = [
'id' => $id,
'name' => Lang::load( Lang::defaultLanguage() )->addToStack( Field::$titleLangPrefix . $id ),
'old' => DataLayer::i()->includeSSOForMember( $this->member ) ? ( is_string( $originalValue ) ? mb_substr( $originalValue, 0, 2048 ) : $originalValue ) : null,
'new' => DataLayer::i()->includeSSOForMember( $this->member ) ? ( is_string( $profileFields[ "field_{$id}" ] ) ? mb_substr( $profileFields[ "field_{$id}" ], 0, 2048 ) : $profileFields[ "field_{$id}" ] ) : null,
];
Lang::load( Lang::defaultLanguage() )->parseOutputForDisplay( $update['name'] );
$dataLayerUpdates['profile_fields'][] = $update;
}
}
$this->member->changedCustomFields = $profileFields;
@@ -1193,6 +1221,17 @@ class profile extends Controller
{
$options['custom'] = 'member_photo_upload';
}
/* Do we have a custom gallery? */
if( Bridge::i()->featureIsEnabled( 'profile_gallery' ) and Settings::i()->cloud_profile_gallery )
{
$options['profile_gallery'] = 'member_profile_gallery';
$toggles['profile_gallery'] = array( 'profile_gallery_id' );
if( $this->member->pp_photo_type == 'cloud_ProfilePhotos' )
{
$defaultType = 'profile_gallery';
}
}
/* Can we use gallery images? */
if ( Application::appIsEnabled('gallery') AND $this->member->pp_photo_type == 'gallery_Images' )
@@ -1262,9 +1301,29 @@ class profile extends Controller
}, NULL, NULL, 'member_photo_upload' ) );
}
/* And generate the profile gallery if we have it */
if( Bridge::i()->featureIsEnabled( 'profile_gallery' ) and Settings::i()->cloud_profile_gallery )
{
$form->add( new Custom( 'profile_gallery_id', null, null, [
'getHtml' => function( $element )
{
return \IPS\cloud\Profiles\Gallery::gallerySelectHtml( $this->member );
},
'validate' => function( $element )
{
if( Request::i()->pp_photo_type == 'profile_gallery' and empty( $element->value ))
{
throw new DomainException( 'form_required' );
}
}
], id: 'profile_gallery_id' ) );
}
/* Handle submissions */
if ( $values = $form->values() )
{
$oldPhotoURL = $this->member->get_photo( false );
/* Disable syncing */
$profileSync = $this->member->profilesync;
if ( isset( $profileSync['photo'] ) )
@@ -1292,6 +1351,10 @@ class profile extends Controller
}
break;
case 'profile_gallery':
\IPS\cloud\Profiles\Gallery::setGalleryPhoto( $this->member, Request::i()->profile_gallery_id );
break;
case 'none':
$this->member->pp_photo_type = NULL;
$this->member->pp_main_photo = NULL;
@@ -1303,6 +1366,30 @@ class profile extends Controller
$this->member->members_bitoptions['profile_completed'] = FALSE;
$this->member->save();
/* Data Layer Stuff */
if ( DataLayer::enabled() and ( $newPhotoURL = $this->member->get_photo( false ) ) and $newPhotoURL !== $oldPhotoURL )
{
try
{
$groupName = Group::load( $this->member->member_group_id )->formattedName;
}
catch ( UnderflowException $e )
{
$groupName = null;
}
$properties = array(
'profile_group' => $groupName,
'profile_group_id' => $this->member->member_group_id ?: null,
'profile_id' => intval( $this->member->member_id ) ?: null,
'profile_name' => $this->member->name ?: null,
'updated_custom_fields' => false,
'updated_profile_name' => false,
'updated_profile_photo' => DataLayer::i()->includeSSOForMember( $this->member ) ? [ 'old' => $oldPhotoURL, 'new' => $newPhotoURL ] : true,
'updated_profile_coverphoto' => false,
);
DataLayer::i()->addEvent( 'social_update', $properties );
}
if ( $this->member->pp_photo_type )
{
@@ -1462,7 +1549,16 @@ class profile extends Controller
}
$limit = array( ( $page - 1 ) * 50, 50 );
$followers = iterator_to_array( $this->member->followers( ( Member::loggedIn()->isAdmin() OR Member::loggedIn()->member_id === $this->member->member_id ) ? \IPS\Content::FOLLOW_PUBLIC + \IPS\Content::FOLLOW_ANONYMOUS : \IPS\Content::FOLLOW_PUBLIC, array( 'immediate', 'daily', 'weekly', 'none' ), NULL, $limit, 'name' ) );
$followerIterator = $this->member->followers( ( Member::loggedIn()->isAdmin() or Member::loggedIn()->member_id === $this->member->member_id ) ? \IPS\Content::FOLLOW_PUBLIC + \IPS\Content::FOLLOW_ANONYMOUS : \IPS\Content::FOLLOW_PUBLIC, ['immediate', 'daily', 'weekly', 'none'], NULL, $limit, 'name' );
if( is_iterable( $followerIterator ) === FALSE )
{
$followers = [];
}
else
{
$followers = iterator_to_array( $followerIterator );
}
$followersCount = $this->member->followersCount( ( Member::loggedIn()->isAdmin() OR Member::loggedIn()->member_id === $this->member->member_id ) ? \IPS\Content::FOLLOW_PUBLIC + \IPS\Content::FOLLOW_ANONYMOUS : \IPS\Content::FOLLOW_PUBLIC, array( 'immediate', 'daily', 'weekly', 'none' ) );
if ( Request::i()->isAjax() )
@@ -1494,6 +1590,9 @@ class profile extends Controller
*/
protected function _coverPhotoSet( CoverPhoto $photo, ?string $type=NULL ) : void
{
$originalPhotoUrl = $this->member->coverPhoto()?->file?->url ?: null;
$originalPhotoUrl = ( is_object( $originalPhotoUrl ) and $originalPhotoUrl instanceof Url ) ? (string) $originalPhotoUrl : $originalPhotoUrl;
/* Disable syncing */
$profileSync = $this->member->profilesync;
if ( isset( $profileSync['cover'] ) )
@@ -1513,6 +1612,32 @@ class profile extends Controller
{
$this->member->logHistory( 'core', 'coverphoto', array( 'action' => $type ) );
}
/* Data Layer Stuff */
$newPhotoUrl = $photo->file?->url ?: null;
$newPhotoUrl = ( is_object( $newPhotoUrl ) and $newPhotoUrl instanceof Url ) ? (string) $newPhotoUrl : $newPhotoUrl;
if ( DataLayer::enabled() and ( $type === 'reposition' or $newPhotoUrl !== $originalPhotoUrl ) )
{
try
{
$groupName = Group::load( $this->member->member_group_id )->formattedName;
}
catch ( UnderflowException $e )
{
$groupName = null;
}
$properties = array(
'profile_group' => $groupName,
'profile_group_id' => $this->member->member_group_id ?: null,
'profile_id' => intval( $this->member->member_id ) ?: null,
'profile_name' => $this->member->name ?: null,
'updated_custom_fields' => false,
'updated_profile_name' => false,
'updated_profile_photo' => false,
'updated_profile_coverphoto' => DataLayer::i()->includeSSOForMember( $this->member ) ? [ 'repositioned' => $type === 'reposition', 'old' => $originalPhotoUrl, 'new' => $newPhotoUrl ] : true,
);
DataLayer::i()->addEvent( 'social_update', $properties );
}
}
/**