Version 5.0.0 beta 1
This commit is contained in:
1 parent
25ddeb65d6
commit
15c7beabc5
6736 files changed
+627902
-497943
No files matched your search
+115
-103
@@ -11,9 +11,29 @@
|
||||
namespace IPS\Content;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Application\Module;
|
||||
use IPS\Db;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\Text;
|
||||
use IPS\Lang;
|
||||
use IPS\Member;
|
||||
use IPS\Member\Club;
|
||||
use IPS\Node\Model;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
use IPS\Settings;
|
||||
use OutOfRangeException;
|
||||
use UnderflowException;
|
||||
use function count;
|
||||
use function defined;
|
||||
use function get_called_class;
|
||||
use function in_array;
|
||||
use function is_array;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
@@ -27,7 +47,7 @@ trait ClubContainer
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function clubIdColumn()
|
||||
public static function clubIdColumn(): string
|
||||
{
|
||||
return 'club_id';
|
||||
}
|
||||
@@ -37,7 +57,7 @@ trait ClubContainer
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function clubFrontTitle()
|
||||
public static function clubFrontTitle(): string
|
||||
{
|
||||
$itemClass = static::$contentItemClass;
|
||||
return $itemClass::$title . '_pl';
|
||||
@@ -48,107 +68,125 @@ trait ClubContainer
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function clubAcpTitle()
|
||||
public static function clubAcpTitle(): string
|
||||
{
|
||||
return static::$nodeTitle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the node can be added as a club feature
|
||||
* This was mainly implemented to handle the club categories,
|
||||
* which are based on database settings.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function canBeAddedToClub() : bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if we need to re-acknowledge rules
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function clubCheckRules()
|
||||
public function clubCheckRules(): void
|
||||
{
|
||||
if ( $club = $this->club() AND !$club->rulesAcknowledged() AND !\IPS\Member::loggedIn()->modPermission( 'can_access_all_clubs' ) )
|
||||
if ( $club = $this->club() AND !$club->rulesAcknowledged() AND !Member::loggedIn()->modPermission( 'can_access_all_clubs' ) )
|
||||
{
|
||||
\IPS\Output::i()->redirect( $club->url()->setQueryString( 'do', 'rules' )->addRef( \IPS\Request::i()->url() ) );
|
||||
Output::i()->redirect( $club->url()->setQueryString( 'do', 'rules' )->addRef( Request::i()->url() ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the associated club
|
||||
*
|
||||
* @return \IPS\Member\Club|NULL
|
||||
* @return Club|NULL
|
||||
*/
|
||||
public function club()
|
||||
public function club(): Club|NULL
|
||||
{
|
||||
if ( \IPS\Settings::i()->clubs )
|
||||
if ( Settings::i()->clubs )
|
||||
{
|
||||
$clubIdColumn = $this->clubIdColumn();
|
||||
if ( $this->$clubIdColumn )
|
||||
{
|
||||
try
|
||||
{
|
||||
return \IPS\Member\Club::load( $this->$clubIdColumn );
|
||||
return Club::load( $this->$clubIdColumn );
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
catch ( OutOfRangeException $e ) { }
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set form for creating a node of this type in a club
|
||||
*
|
||||
* @param \IPS\Helpers\Form $form Form object
|
||||
* @return void
|
||||
* @param Form $form Form object
|
||||
* @param Club $club
|
||||
* @return void
|
||||
*/
|
||||
public function clubForm( \IPS\Helpers\Form $form, \IPS\Member\Club $club )
|
||||
public function clubForm( Form $form, Club $club ): void
|
||||
{
|
||||
$itemClass = static::$contentItemClass;
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'club_node_name', $this->_id ? $this->_title : \IPS\Member::loggedIn()->language()->addToStack( static::clubFrontTitle() ), TRUE, array( 'maxLength' => 255 ) ) );
|
||||
$form->add( new Text( 'club_node_name', $this->_id ? $this->_title : Member::loggedIn()->language()->addToStack( static::clubFrontTitle() ), TRUE, array( 'maxLength' => 255 ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Save club form
|
||||
*
|
||||
* @param \IPS\Member\Club $club The club
|
||||
* @param Club $club The club
|
||||
* @param array $values Values
|
||||
* @return void
|
||||
*/
|
||||
public function saveClubForm( \IPS\Member\Club $club, $values )
|
||||
public function saveClubForm( Club $club, array $values ): void
|
||||
{
|
||||
$nodeClass = \get_called_class();
|
||||
/* @var Model $nodeClass */
|
||||
$nodeClass = get_called_class();
|
||||
$itemClass = $nodeClass::$contentItemClass;
|
||||
|
||||
$clubIdColumn = $this->clubIdColumn();
|
||||
$haveId = (bool) $this->_id;
|
||||
|
||||
|
||||
/* We want to make sure the club ID is set before we
|
||||
run the _saveClubForm method */
|
||||
if( !$haveId )
|
||||
{
|
||||
$this->$clubIdColumn = $club->id;
|
||||
}
|
||||
|
||||
$this->_saveClubForm( $club, $values );
|
||||
|
||||
|
||||
$needToUpdatePermissions = FALSE;
|
||||
|
||||
if ( !$haveId )
|
||||
{
|
||||
$clubIdColumn = $this->clubIdColumn();
|
||||
$this->$clubIdColumn = $club->id;
|
||||
$this->save();
|
||||
\IPS\Db::i()->insert( 'core_clubs_node_map', array(
|
||||
|
||||
Db::i()->insert( 'core_clubs_node_map', array(
|
||||
'club_id' => $club->id,
|
||||
'node_class' => $nodeClass,
|
||||
'node_id' => $this->_id,
|
||||
'name' => $values['club_node_name'],
|
||||
'public' => ( isset( $values['club_node_public'] ) ) ? $values['club_node_public'] : 0
|
||||
'public' => $values['club_node_public'] ?? 0
|
||||
) );
|
||||
|
||||
$needToUpdatePermissions = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( $this instanceof \IPS\cms\Categories )
|
||||
{
|
||||
$values['club_node_public'] = \intval( \in_array( 'member', explode( ',', $this->club_view_permission ) ) or \mb_strpos( '*', $this->club_view_permission ) !== false );
|
||||
}
|
||||
if( isset( $values['club_node_public'] ) AND $values['club_node_public'] != $this->isPublic() )
|
||||
{
|
||||
$needToUpdatePermissions = TRUE;
|
||||
}
|
||||
|
||||
$this->save();
|
||||
\IPS\Db::i()->update( 'core_clubs_node_map', array( 'name' => $values['club_node_name'], 'public' => isset( $values['club_node_public'] ) ? (int) $values['club_node_public'] : 0), array( 'club_id=? AND node_class=? AND node_id=?', $club->id, $nodeClass, $this->_id ) );
|
||||
Db::i()->update( 'core_clubs_node_map', array( 'name' => $values['club_node_name'], 'public' => isset( $values['club_node_public'] ) ? (int) $values['club_node_public'] : 0), array( 'club_id=? AND node_class=? AND node_id=?', $club->id, $nodeClass, $this->_id ) );
|
||||
}
|
||||
|
||||
\IPS\Lang::saveCustom( $itemClass::$application, static::$titleLangPrefix . $this->_id, $values['club_node_name'] );
|
||||
\IPS\Lang::saveCustom( $itemClass::$application, static::$titleLangPrefix . $this->_id . '_desc', isset( $values['club_node_description'] ) ? $values['club_node_description'] : '' );
|
||||
Lang::saveCustom( $itemClass::$application, static::$titleLangPrefix . $this->_id, $values['club_node_name'] );
|
||||
Lang::saveCustom( $itemClass::$application, static::$titleLangPrefix . $this->_id . '_desc', $values['club_node_description'] ?? '' );
|
||||
|
||||
if ( $needToUpdatePermissions )
|
||||
{
|
||||
@@ -157,18 +195,19 @@ trait ClubContainer
|
||||
|
||||
if ( !$haveId )
|
||||
{
|
||||
/* @var string $nodeClass */
|
||||
$followApp = $itemClass::$application;
|
||||
$followArea = mb_strtolower( mb_substr( $nodeClass, mb_strrpos( $nodeClass, '\\' ) + 1 ) );
|
||||
$time = time();
|
||||
$follows = array();
|
||||
foreach( \IPS\Db::i()->select( "MD5( CONCAT( '{$followApp};{$followArea};{$this->_id};', follow_member_id ) ) AS follow_id, '{$followApp}' AS follow_app, '{$followArea}' AS follow_area, '{$this->_id}' AS follow_rel_id, follow_member_id, follow_is_anon, '{$time}' AS follow_added, follow_notify_do, follow_notify_meta, follow_notify_freq, 0 AS follow_notify_sent, follow_visible", 'core_follow', array( 'follow_app=? AND follow_area=? AND follow_rel_id=?', 'core', 'club', $club->id ) ) AS $follow )
|
||||
foreach( Db::i()->select( "MD5( CONCAT( '{$followApp};{$followArea};{$this->_id};', follow_member_id ) ) AS follow_id, '{$followApp}' AS follow_app, '{$followArea}' AS follow_area, '{$this->_id}' AS follow_rel_id, follow_member_id, follow_is_anon, '{$time}' AS follow_added, follow_notify_do, follow_notify_meta, follow_notify_freq, 0 AS follow_notify_sent, follow_visible", 'core_follow', array( 'follow_app=? AND follow_area=? AND follow_rel_id=?', 'core', 'club', $club->id ) ) AS $follow )
|
||||
{
|
||||
$follows[] = $follow;
|
||||
}
|
||||
|
||||
if ( \count( $follows ) )
|
||||
if ( count( $follows ) )
|
||||
{
|
||||
\IPS\Db::i()->insert( 'core_follow', $follows );
|
||||
Db::i()->insert( 'core_follow', $follows );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -176,11 +215,11 @@ trait ClubContainer
|
||||
/**
|
||||
* Class-specific routine when saving club form
|
||||
*
|
||||
* @param \IPS\Member\Club $club The club
|
||||
* @param Club $club The club
|
||||
* @param array $values Values
|
||||
* @return void
|
||||
*/
|
||||
public function _saveClubForm( \IPS\Member\Club $club, $values )
|
||||
public function _saveClubForm( Club $club, array $values ): void
|
||||
{
|
||||
// Deliberately does nothing so classes can override
|
||||
}
|
||||
@@ -188,19 +227,19 @@ trait ClubContainer
|
||||
/**
|
||||
* Set the permission index permissions to a specific club
|
||||
*
|
||||
* @param \IPS\Member\Club $club The club
|
||||
* @param Club $club The club
|
||||
* @return void
|
||||
*/
|
||||
public function setPermissionsToClub( \IPS\Member\Club $club )
|
||||
public function setPermissionsToClub( Club $club ): void
|
||||
{
|
||||
/* Delete current rows */
|
||||
\IPS\Db::i()->delete( 'core_permission_index', array( 'app=? AND perm_type=? AND perm_type_id=?', static::$permApp, static::$permType, $this->_id ) );
|
||||
Db::i()->delete( 'core_permission_index', array( 'app=? AND perm_type=? AND perm_type_id=?', static::$permApp, static::$permType, $this->_id ) );
|
||||
|
||||
/* Build new rows */
|
||||
$insert = array( 'app' => static::$permApp, 'perm_type' => static::$permType, 'perm_type_id' => $this->_id );
|
||||
foreach ( static::$permissionMap as $k => $v )
|
||||
{
|
||||
if ( \in_array( $k, array( 'view', 'read' ) ) )
|
||||
if ( in_array( $k, array( 'view', 'read' ) ) )
|
||||
{
|
||||
switch ( $club->type )
|
||||
{
|
||||
@@ -217,7 +256,7 @@ trait ClubContainer
|
||||
break;
|
||||
}
|
||||
}
|
||||
elseif ( \in_array( $k, array( 'add', 'edit', 'reply', 'review' ) ) )
|
||||
elseif ( in_array( $k, array( 'add', 'edit', 'reply', 'review' ) ) )
|
||||
{
|
||||
switch ( $club->type )
|
||||
{
|
||||
@@ -253,12 +292,12 @@ trait ClubContainer
|
||||
}
|
||||
|
||||
/* Insert */
|
||||
$permId = \IPS\Db::i()->insert( 'core_permission_index', $insert );
|
||||
$permId = Db::i()->insert( 'core_permission_index', $insert );
|
||||
|
||||
/* Update tags permission cache */
|
||||
if ( isset( static::$permissionMap['read'] ) )
|
||||
{
|
||||
\IPS\Db::i()->update( 'core_tags_perms', array( 'tag_perm_text' => $insert[ 'perm_' . static::$permissionMap['read'] ] ), array( 'tag_perm_aap_lookup=?', md5( static::$permApp . ';' . static::$permType . ';' . $this->_id ) ) );
|
||||
Db::i()->update( 'core_tags_perms', array( 'tag_perm_text' => $insert[ 'perm_' . static::$permissionMap['read'] ] ), array( 'tag_perm_aap_lookup=?', md5( static::$permApp . ';' . static::$permType . ';' . $this->_id ) ) );
|
||||
}
|
||||
|
||||
/* Make sure this object resets the permissions internally */
|
||||
@@ -272,18 +311,18 @@ trait ClubContainer
|
||||
* Fetch All Root Nodes
|
||||
*
|
||||
* @param string|NULL $permissionCheck The permission key to check for or NULL to not check permissions
|
||||
* @param \IPS\Member|NULL $member The member to check permissions for or NULL for the currently logged in member
|
||||
* @param Member|NULL $member The member to check permissions for or NULL for the currently logged in member
|
||||
* @param mixed $where Additional WHERE clause
|
||||
* @param array|NULL $limit Limit/offset to use, or NULL for no limit (default)
|
||||
* @return array
|
||||
*/
|
||||
public static function rootsWithClubs( $permissionCheck='view', $member=NULL, $where=array(), $limit=NULL )
|
||||
public static function rootsWithClubs( ?string $permissionCheck='view', Member $member=NULL, mixed $where=array(), array|null $limit=NULL ): array
|
||||
{
|
||||
/* Will we need to check permissions? */
|
||||
$usingPermssions = ( \in_array( 'IPS\Node\Permissions', class_implements( \get_called_class() ) ) and $permissionCheck !== NULL );
|
||||
$usingPermssions = ( in_array( 'IPS\Node\Permissions', class_implements( get_called_class() ) ) and $permissionCheck !== NULL );
|
||||
if ( $usingPermssions )
|
||||
{
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
$member = $member ?: Member::loggedIn();
|
||||
}
|
||||
|
||||
if( static::$databaseColumnParent !== NULL )
|
||||
@@ -304,17 +343,17 @@ trait ClubContainer
|
||||
/**
|
||||
* @brief Cached club nodes
|
||||
*/
|
||||
protected static $cachedClubNodes = NULL;
|
||||
protected static array|null $cachedClubNodes = NULL;
|
||||
|
||||
/**
|
||||
* Fetch All Nodes in Clubs
|
||||
*
|
||||
* @param string|NULL $permissionCheck The permission key to check for or NULl to not check permissions
|
||||
* @param \IPS\Member|NULL $member The member to check permissions for or NULL for the currently logged in member
|
||||
* @param Member|NULL $member The member to check permissions for or NULL for the currently logged in member
|
||||
* @param mixed $where Additional WHERE clause
|
||||
* @return array
|
||||
*/
|
||||
public static function clubNodes( $permissionCheck='view', $member=NULL, $where=array() )
|
||||
public static function clubNodes( string|null $permissionCheck='view', Member|null $member=NULL, mixed $where=array() ): array
|
||||
{
|
||||
if( static::$cachedClubNodes === NULL )
|
||||
{
|
||||
@@ -322,21 +361,11 @@ trait ClubContainer
|
||||
|
||||
$where[] = array( static::$databasePrefix . $clubIdColumn . ' IS NOT NULL' );
|
||||
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
$member = $member ?: Member::loggedIn();
|
||||
|
||||
if( $member->canAccessModule( \IPS\Application\Module::get( 'core', 'clubs', 'front' ) ) )
|
||||
if( $member->canAccessModule( Module::get( 'core', 'clubs', 'front' ) ) )
|
||||
{
|
||||
/* nodesWithPermission joins on the permissions table, which is not used for club categories */
|
||||
$nodes = [];
|
||||
foreach( static::nodesWithPermission( $permissionCheck, $member, $where ) as $node )
|
||||
{
|
||||
if( !( $node instanceof \IPS\cms\Categories ) or ( $permissionCheck AND $node->can( $permissionCheck ) ) )
|
||||
{
|
||||
$nodes[] = $node;
|
||||
}
|
||||
}
|
||||
|
||||
static::$cachedClubNodes = $nodes;
|
||||
static::$cachedClubNodes = static::nodesWithPermission( $permissionCheck, $member, $where );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -348,14 +377,17 @@ trait ClubContainer
|
||||
|
||||
foreach( static::$cachedClubNodes as $node )
|
||||
{
|
||||
$clubIds[] = $node->$clubIdColumn;
|
||||
if ( $node->$clubIdColumn )
|
||||
{
|
||||
$clubIds[] = $node->$clubIdColumn;
|
||||
}
|
||||
}
|
||||
|
||||
if( \count( $clubIds ) )
|
||||
if( count( $clubIds ) )
|
||||
{
|
||||
foreach( \IPS\Db::i()->select( '*', 'core_clubs', array( 'id IN(' . implode( ',', $clubIds ) . ')' ) ) as $clubData )
|
||||
foreach( Db::i()->select( '*', 'core_clubs', array( 'id IN(' . implode( ',', $clubIds ) . ')' ) ) as $clubData )
|
||||
{
|
||||
\IPS\Member\Club::constructFromData( $clubData );
|
||||
Club::constructFromData( $clubData );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -366,14 +398,14 @@ trait ClubContainer
|
||||
/**
|
||||
* Check Moderator Permission
|
||||
*
|
||||
* @param string $type 'edit', 'hide', 'unhide', 'delete', etc.
|
||||
* @param \IPS\Member|NULL $member The member to check for or NULL for the currently logged in member
|
||||
* @param string $class The class to check against
|
||||
* @param string $type 'edit', 'hide', 'unhide', 'delete', etc.
|
||||
* @param Member|NULL $member The member to check for or NULL for the currently logged in member
|
||||
* @param string $class The class to check against
|
||||
* @return bool
|
||||
*/
|
||||
public function modPermission( $type, \IPS\Member $member, $class )
|
||||
public function clubContainerPermission( string $type, Member|null $member, string $class ): bool
|
||||
{
|
||||
if ( \IPS\Settings::i()->clubs )
|
||||
if ( Settings::i()->clubs )
|
||||
{
|
||||
$clubIdColumn = $this->clubIdColumn();
|
||||
|
||||
@@ -382,16 +414,16 @@ trait ClubContainer
|
||||
|
||||
if ( $this->$clubIdColumn and $club = $this->club() )
|
||||
{
|
||||
if ( \in_array( $club->memberStatus( $member ), array( \IPS\Member\Club::STATUS_LEADER, \IPS\Member\Club::STATUS_MODERATOR ) ) )
|
||||
if ( in_array( $club->memberStatus( $member ), array( Club::STATUS_LEADER, Club::STATUS_MODERATOR ) ) )
|
||||
{
|
||||
if ( \in_array( $type, explode( ',', \IPS\Settings::i()->clubs_modperms ) ) )
|
||||
if ( in_array( $type, explode( ',', Settings::i()->clubs_modperms ) ) )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
elseif ( $member->modPermission( "can_{$type}_{$title}" ) and \is_array( $member->modPermission( static::$modPerm ) ) and $member->modPermission('can_access_all_clubs') )
|
||||
elseif ( $member->modPermission( "can_{$type}_{$title}" ) and is_array( $member->modPermission( static::$modPerm ) ) and $member->modPermission('can_access_all_clubs') )
|
||||
{
|
||||
if ( \in_array( $type, explode( ',', \IPS\Settings::i()->clubs_modperms ) ) )
|
||||
if ( in_array( $type, explode( ',', Settings::i()->clubs_modperms ) ) )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
@@ -399,27 +431,7 @@ trait ClubContainer
|
||||
}
|
||||
}
|
||||
|
||||
return parent::modPermission( $type, $member, $class );
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Get parent list
|
||||
*
|
||||
* @return \SplStack
|
||||
*/
|
||||
public function parents()
|
||||
{
|
||||
$clubIdColumn = static::clubIdColumn();
|
||||
|
||||
/* Only do this if this node is actually associated with a club */
|
||||
if ( $this->$clubIdColumn )
|
||||
{
|
||||
return new \SplStack;
|
||||
}
|
||||
else
|
||||
{
|
||||
return parent::parents();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -427,13 +439,13 @@ trait ClubContainer
|
||||
*
|
||||
* @return int 0 = not public, 1 = anyone can view, 2 = anyone can participate
|
||||
*/
|
||||
public function isPublic()
|
||||
public function isPublic(): int
|
||||
{
|
||||
try
|
||||
{
|
||||
return (int) \IPS\Db::i()->select( 'public', 'core_clubs_node_map', array( 'club_id=? AND node_class=? AND node_id=?', $this->club()->id, \get_called_class(), $this->_id ) )->first();
|
||||
return (int) Db::i()->select( 'public', 'core_clubs_node_map', array( 'club_id=? AND node_class=? AND node_id=?', $this->club()->id, get_called_class(), $this->_id ) )->first();
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
catch ( UnderflowException $e )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user