Version 5.0.6
This commit is contained in:
1 parent
a3a4a9ccbd
commit
b89858b2ff
1214 files changed
+92828
-14859
No files matched your search
+256
-4
@@ -44,6 +44,9 @@ use IPS\Helpers\Form\Text;
|
||||
use IPS\Helpers\Form\TextArea;
|
||||
use IPS\Helpers\Form\Upload;
|
||||
use IPS\Helpers\Form\YesNo;
|
||||
use IPS\Helpers\Menu;
|
||||
use IPS\Helpers\Menu\Buttons;
|
||||
use IPS\Helpers\Menu\Link;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Http\Url\Friendly;
|
||||
use IPS\IPS;
|
||||
@@ -52,6 +55,7 @@ use IPS\Log;
|
||||
use IPS\Math\Number;
|
||||
use IPS\Member;
|
||||
use IPS\Member\Club\CustomField;
|
||||
use IPS\Member\Club\Page as ClubPage;
|
||||
use IPS\nexus\Customer;
|
||||
use IPS\nexus\Invoice;
|
||||
use IPS\nexus\Money;
|
||||
@@ -930,6 +934,7 @@ class Club extends ActiveRecord implements Embeddable
|
||||
{
|
||||
return [];
|
||||
}
|
||||
$values = array_filter( $values, function ( $val) { return ( $val !== '' AND $val !== NULL ); } );
|
||||
|
||||
return $values;
|
||||
}
|
||||
@@ -944,9 +949,10 @@ class Club extends ActiveRecord implements Embeddable
|
||||
*
|
||||
* @param bool $getOverlay If FALSE, will not set the overlay, which saves queries if it will not be used (such as in clubCard)
|
||||
* @param string $position Position of cover photo
|
||||
* @param Model|ClubPage|null $container Node or Page currently viewing
|
||||
* @return CoverPhoto
|
||||
*/
|
||||
public function coverPhoto( bool $getOverlay=TRUE, string $position='full' ): CoverPhoto
|
||||
public function coverPhoto( bool $getOverlay=TRUE, string $position='full', Model|ClubPage|null $container=null ): CoverPhoto
|
||||
{
|
||||
$photo = new CoverPhoto;
|
||||
|
||||
@@ -958,7 +964,7 @@ class Club extends ActiveRecord implements Embeddable
|
||||
}
|
||||
if ( $getOverlay )
|
||||
{
|
||||
$photo->overlay = Theme::i()->getTemplate( 'clubs', 'core', 'front' )->coverPhotoOverlay( $this, $position );
|
||||
$photo->overlay = Theme::i()->getTemplate( 'clubs', 'core', 'front' )->coverPhotoOverlay( $this, $position, $container );
|
||||
}
|
||||
$photo->editable = $this->isLeader();
|
||||
$photo->object = $this;
|
||||
@@ -1491,12 +1497,19 @@ class Club extends ActiveRecord implements Embeddable
|
||||
{
|
||||
$class = $row['node_class'];
|
||||
$classBits = explode( '\\', $class );
|
||||
|
||||
if( !Application::load( $classBits[1] )->_enabled )
|
||||
try
|
||||
{
|
||||
if( !Application::load( $classBits[1] )->_enabled )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
catch( \OutOfRangeException $e)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
/* Make sure the class exists. This can happen in the case of Pages databases/categories */
|
||||
if( !class_exists( $row['node_class'] ) )
|
||||
{
|
||||
@@ -2097,6 +2110,207 @@ class Club extends ActiveRecord implements Embeddable
|
||||
return static::$tabs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the club menu
|
||||
*
|
||||
* @param Model|ClubPage|null $container
|
||||
* @return Menu
|
||||
*/
|
||||
public function menu( Model|ClubPage|null $container = null ) : Menu
|
||||
{
|
||||
$menu = new Menu( 'club_manage', css: 'ipsButton ipsButton--inherit' );
|
||||
if( Settings::i()->clubs_header == 'sidebar' )
|
||||
{
|
||||
$menu->css .= ' i-width_100p i-margin-top_2';
|
||||
}
|
||||
|
||||
if( !$this->isLeader() and $this->owner->member_id != Member::loggedIn()->member_id and !Member::loggedIn()->modPermission( 'can_access_all_clubs' ) )
|
||||
{
|
||||
return $menu;
|
||||
}
|
||||
|
||||
if( !Settings::i()->clubs_require_approval or $this->approved )
|
||||
{
|
||||
if ( $this->isLeader() and $nodeTypes = static::availableNodeTypes() )
|
||||
{
|
||||
foreach( $nodeTypes as $nodeType )
|
||||
{
|
||||
$menu->add( new Link( $this->url()->setQueryString( [ 'do' => 'nodeForm', 'type' => $nodeType ] ), $nodeType::clubFrontTitle(), dataAttributes: [ 'data-ipsDialog-title' => Member::loggedIn()->language()->addToStack( 'club_create_node' ) ], opensDialog: true ) );
|
||||
}
|
||||
}
|
||||
|
||||
if( ( $this->owner and $this->owner->member_id == Member::loggedIn()->member_id ) or Member::loggedIn()->modPermission( 'can_access_all_clubs' ) or Member::loggedIn()->modPermission( 'can_manage_featured_clubs' ) )
|
||||
{
|
||||
$menu->addSeparator();
|
||||
}
|
||||
}
|
||||
|
||||
if( $this->isLeader() )
|
||||
{
|
||||
$menu->add( new Link( $this->url()->setQueryString( 'do', 'editPhoto' ), 'club_profile_photo', dataAttributes: [
|
||||
'data-ipsDialog' => true,
|
||||
'data-ipsDialog-modal' => true,
|
||||
'data-ipsDialog-forceReload' => true,
|
||||
'data-ipsDialog-title' => Member::loggedIn()->language()->addToStack( 'club_profile_photo' ),
|
||||
'data-action' => 'editPhoto'
|
||||
] ) );
|
||||
}
|
||||
|
||||
if( ( $this->owner and $this->owner->member_id == Member::loggedIn()->member_id ) or Member::loggedIn()->modPermission( 'can_access_all_clubs' ) )
|
||||
{
|
||||
$menu->add( new Link( $this->url()->setQueryString( 'do', 'edit' ), 'club_edit_settings', opensDialog: true ) );
|
||||
}
|
||||
|
||||
if( Member::loggedIn()->modPermission( 'can_manage_featured_clubs' ) )
|
||||
{
|
||||
if( $this->featured )
|
||||
{
|
||||
$menu->add( new Link( $this->url()->csrf()->setQueryString( 'do', 'unfeature' ), 'club_unfeature', dataAttributes: [ 'data-confirm' => '' ] ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$menu->add( new Link( $this->url()->csrf()->setQueryString( 'do', 'feature' ), 'club_feature', dataAttributes: [ 'data-confirm' => '' ] ) );
|
||||
}
|
||||
}
|
||||
|
||||
if( $this->canInvite() )
|
||||
{
|
||||
$menu->add( new Link( $this->url()->setQueryString( 'do', 'invite' ), 'club_invite_members', dataAttributes: [ 'data-ipsDialog-size' => 'narrow' ], opensDialog: true ) );
|
||||
}
|
||||
|
||||
if( $this->canManageNavigation() and $container instanceof Model and count( $this->tabs( $container ) ) > 1 )
|
||||
{
|
||||
$menu->add( new Link( '#', 'reorder_club_menu', dataAttributes: [ 'data-action' => 'reorderClubmenu' ] ) );
|
||||
}
|
||||
|
||||
if( ClubPage::canAdd( $this ) )
|
||||
{
|
||||
$menu->add( new Link( $this->url()->setQueryString( 'do', 'addPage' ), 'club_add_page', dataAttributes: [
|
||||
'data-ipsDialog-title' => Member::loggedIn()->language()->addToStack( 'add_page_to_club', true, [ 'sprintf' => $this->name ] )
|
||||
], opensDialog: true ) );
|
||||
}
|
||||
|
||||
if( $container instanceof ClubPage)
|
||||
{
|
||||
if( $container->canEdit() )
|
||||
{
|
||||
$menu->add( new Link( $container->url( 'edit' ), 'edit_page', opensDialog: true ) );
|
||||
}
|
||||
if( $container->canDelete() )
|
||||
{
|
||||
$menu->add( new Link( $container->url( 'delete' )->csrf(), 'delete_page', dataAttributes: [ 'data-confirm' => '' ] ) );
|
||||
}
|
||||
}
|
||||
|
||||
if( $container instanceof Model and $this->isLeader() )
|
||||
{
|
||||
$menu->addSeparator();
|
||||
$menu->add( new Link( $this->url()->setQueryString( [ 'do' => 'nodeForm', 'type' => get_class( $container ), 'node' => $container->_id ] ), Member::loggedIn()->language()->addToStack( 'clubs_edit_this_container', true, [ 'sprintf' => Member::loggedIn()->language()->addToStack( $container::$nodeTitle . '_sg' ) ] ), dataAttributes: [ 'data-ipsDialog-title' => $container->_title ], opensDialog: true ) );
|
||||
|
||||
if( isset( $container::$contentItemClass ) and $itemClass = $container::$contentItemClass and ( $container->modPermission( 'delete', Member::loggedIn(), $itemClass ) or !!$itemClass::contentCount( $container, true, true, true, 1 ) ) )
|
||||
{
|
||||
$menu->add( new Link( $this->url()->setQueryString( [ 'do' => 'nodeDelete', 'type' => get_class( $container ), 'node' => $container->_id] )->csrf(), Member::loggedIn()->language()->addToStack( 'clubs_delete_this_container', true, [ 'sprintf' => Member::loggedIn()->language()->addToStack( $container::$nodeTitle . '_sg' ) ] ), dataAttributes: [ 'data-confirm' => '', 'data-confirmSubMessage' => Member::loggedIn()->language()->addToStack( 'clubs_delete_container_confirm' ) ] ) );
|
||||
}
|
||||
}
|
||||
|
||||
/* Extensions */
|
||||
foreach( Application::allExtensions( 'core', 'Club' ) AS $ext )
|
||||
{
|
||||
foreach( $ext->menu( $this, $container ) as $link )
|
||||
{
|
||||
$menu->add( $link );
|
||||
}
|
||||
}
|
||||
|
||||
return $menu;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a buttons list for the club header
|
||||
*
|
||||
* @return Buttons
|
||||
*/
|
||||
public function buttons() : Buttons
|
||||
{
|
||||
$buttons = new Buttons();
|
||||
|
||||
$memberStatus = $this->memberStatus( Member::loggedIn() );
|
||||
if( $this->type !== static::TYPE_PUBLIC )
|
||||
{
|
||||
if( $memberStatus === static::STATUS_BANNED )
|
||||
{
|
||||
$buttons->addButton( null, 'club_banned_title', icon: 'fa-solid fa-xmark', tooltip: 'club_banned_desc_short' );
|
||||
}
|
||||
elseif( in_array( $memberStatus, [ static::STATUS_MEMBER, static::STATUS_MODERATOR, static::STATUS_LEADER, static::STATUS_EXPIRED, static::STATUS_EXPIRED_MODERATOR, static::STATUS_WAITING_PAYMENT ] ) )
|
||||
{
|
||||
if( $memberStatus === static::STATUS_WAITING_PAYMENT )
|
||||
{
|
||||
$buttons->addButton( $this->url()->setQueryString( 'do', 'join' )->csrf(), 'club_pay_membership_fee' );
|
||||
}
|
||||
if( in_array( $memberStatus, [ static::STATUS_EXPIRED, static::STATUS_EXPIRED_MODERATOR ] ) )
|
||||
{
|
||||
$buttons->addButton( $this->url()->setQueryString( 'do', 'renew' )->csrf(), 'club_renew_membership' );
|
||||
}
|
||||
if( !$this->owner or $this->owner->member_id != Member::loggedIn()->member_id )
|
||||
{
|
||||
$attributes = [ 'data-confirm' => '' ];
|
||||
if( $this->isPaid() )
|
||||
{
|
||||
$attributes['data-confirmSubMessage'] = Member::loggedIn()->language()->addToStack( 'club_leave_paid_warning' );
|
||||
}
|
||||
$buttons->addButton( $this->url()->setQueryString( 'do', 'leave' )->csrf(), 'club_leave', dataAttributes: $attributes );
|
||||
}
|
||||
}
|
||||
elseif( $this->canJoin() )
|
||||
{
|
||||
/* We skip the join button for the sidebar view; it's shown somewhere else */
|
||||
if( Settings::i()->clubs_header != 'sidebar' )
|
||||
{
|
||||
$attributes = [];
|
||||
if( $this->isPaid() and $memberStatus !== static::STATUS_INVITED_BYPASSING_PAYMENT )
|
||||
{
|
||||
$attributes = [
|
||||
'data-confirm' => '',
|
||||
'data-confirmIcon' => 'info',
|
||||
'data-confirmMessage' => Member::loggedIn()->language()->addToStack( 'club_membership_item' ),
|
||||
'data-confirmSubmessage' => Member::loggedIn()->language()->addToStack( $this->memberFeeMessage() )
|
||||
];
|
||||
}
|
||||
$buttons->addButton( $this->url()->csrf()->setQueryString( 'do', 'join' )->addRef( Request::i()->url() ), 'club_join', dataAttributes: $attributes );
|
||||
}
|
||||
}
|
||||
elseif( !$this->canRead() )
|
||||
{
|
||||
if( $memberStatus === static::STATUS_REQUESTED )
|
||||
{
|
||||
$buttons->addButton( $this->url()->csrf()->setQueryString( 'do', 'cancelJoin' ), 'club_cancel_request', 'ipsButton ipsButton--text', icon: 'fa-solid fa-xmark' );
|
||||
}
|
||||
elseif( $memberStatus === static::STATUS_DECLINED )
|
||||
{
|
||||
$buttons->addButton( null, 'club_denied_title', dataAttributes: [ 'aria-disabled' => 'true' ], icon: 'fa-solid fa-xmark', tooltip: Member::loggedIn()->language()->addToStack( 'club_denied_desc_short' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Extensions */
|
||||
foreach( Application::allExtensions( 'core', 'Club' ) AS $ext )
|
||||
{
|
||||
foreach( $ext->buttons( $this ) as $button )
|
||||
{
|
||||
if( is_string( $button ) )
|
||||
{
|
||||
$buttons->addHtml( $button );
|
||||
}
|
||||
else
|
||||
{
|
||||
$buttons->add( $button );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $buttons;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can a member view the members page
|
||||
*
|
||||
@@ -2383,4 +2597,42 @@ class Club extends ActiveRecord implements Embeddable
|
||||
|
||||
$purchase->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate through all the club nodes and set the last_activity
|
||||
*
|
||||
* @param Member|null $member
|
||||
* @return void
|
||||
*/
|
||||
public function updateLastActivityAndItemCount( Member $member = null ) : void
|
||||
{
|
||||
$member = $member ?: Member::loggedIn();
|
||||
$this->content = 0;
|
||||
$this->last_activity = 0;
|
||||
|
||||
foreach ( $this->nodes() as $node )
|
||||
{
|
||||
try
|
||||
{
|
||||
$nodeClass = $node['node_class'];
|
||||
if ( ! class_exists( $nodeClass ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$node = $nodeClass::load( $node['node_id'] );
|
||||
|
||||
if ( $lastCommentTime = $node->getLastCommentTime( $member ) and $lastCommentTime->getTimestamp() > $this->last_activity )
|
||||
{
|
||||
$this->last_activity = $lastCommentTime->getTimestamp();
|
||||
}
|
||||
|
||||
$this->content += (int) $node->getContentItemCount();
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
}
|
||||
|
||||
$this->rebuilt = time();
|
||||
$this->save();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user