Version 4.7.0
This commit is contained in:
1 parent
517a5e1f70
commit
8ba7d43898
1933 files changed
+65613
-11332
No files matched your search
@@ -390,7 +390,6 @@ class _Controller extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Build form */
|
||||
$form = $this->_addEditForm( $node );
|
||||
|
||||
@@ -1121,10 +1120,22 @@ class _Controller extends \IPS\Dispatcher\Controller
|
||||
$matrix = new \IPS\Helpers\Form\Matrix;
|
||||
$matrix->manageable = FALSE;
|
||||
$matrix->langPrefix = $nodeClass::$permissionLangPrefix . 'perm__';
|
||||
$matrix->styledRowTitle = TRUE;
|
||||
$matrix->columns = array(
|
||||
'label' => function( $key, $value, $data )
|
||||
{
|
||||
return $value;
|
||||
$groupId = explode( '[', $key )[0];
|
||||
$groupLink = NULL;
|
||||
|
||||
/* Let's try to get a link to the group's permissions */
|
||||
try
|
||||
{
|
||||
\IPS\Member\Group::load( $groupId );
|
||||
$groupLink = \IPS\Http\Url::internal( "app=core&module=members&controller=groups&do=permissions&id=" . $groupId );
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->titleWithLink( $value, $groupLink, 'all_permissions', \IPS\Member::loggedIn()->language()->addToStack( "all_permissions_group_hovertitle", FALSE, array( 'sprintf' => [ $value ] ) ) );
|
||||
},
|
||||
);
|
||||
|
||||
@@ -1156,7 +1167,7 @@ class _Controller extends \IPS\Dispatcher\Controller
|
||||
|
||||
if ( $disabled === FALSE )
|
||||
{
|
||||
$disabled = ( $groupId == \IPS\Settings::i()->guest_group AND \in_array( $k, array('review', 'rate' ) ) ) ? TRUE : FALSE;
|
||||
$disabled = ( $groupId == \IPS\Settings::i()->guest_group AND \in_array( $k, array( 'review', 'rate' ) ) ) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
$fieldValue = ( isset( $current[ "perm_{$v}" ] ) and ( $current[ "perm_{$v}" ] === '*' or \in_array( $groupId, explode( ',', $current[ "perm_{$v}" ] ) ) ) );
|
||||
|
||||
+150
-10
@@ -511,6 +511,38 @@ abstract class _Model extends \IPS\Patterns\ActiveRecord
|
||||
throw new \BadMethodCallException;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Cached AdminCP urls
|
||||
*/
|
||||
protected $_acpUrls = array();
|
||||
|
||||
/**
|
||||
* @brief The class of the ACP \IPS\Node\Controller that manages this node type
|
||||
*/
|
||||
protected static $acpController = NULL;
|
||||
|
||||
/**
|
||||
* Get the URL of the AdminCP page for this node
|
||||
*
|
||||
* @param string|NULL $do The "do" query parameter of the url (e.g. 'form', 'permissions', etc).
|
||||
*
|
||||
* @return \IPS\Http\Url | NULL
|
||||
*/
|
||||
public function acpUrl( $do="form" )
|
||||
{
|
||||
if ( !isset( $this->acpUrls[$do] ) AND static::$acpController !== NULL )
|
||||
{
|
||||
/* Does the method exist? */
|
||||
if ( method_exists( static::$acpController, $do ) )
|
||||
{
|
||||
$bits = explode( "\\", static::$acpController );
|
||||
$acpUrlBase = "app={$bits[1]}&module={$bits[4]}&controller={$bits[5]}";
|
||||
$this->_acpUrls[$do] = \IPS\Http\Url::internal( $acpUrlBase )->setQueryString( array( 'do' => $do, 'id' => $this->_id ) );
|
||||
}
|
||||
}
|
||||
return $this->_acpUrls[$do] ?? NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Columns needed to query for search result / stream view
|
||||
*
|
||||
@@ -738,7 +770,7 @@ abstract class _Model extends \IPS\Patterns\ActiveRecord
|
||||
{
|
||||
if ( static::$titleLangPrefix and static::$descriptionLangSuffix )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( static::$titleLangPrefix . $this->id . static::$descriptionLangSuffix, FALSE, array( 'striptags' => TRUE, 'escape' => TRUE ) );
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( static::$titleLangPrefix . $this->id . static::$descriptionLangSuffix, FALSE, array( 'striptags' => TRUE, 'escape' => TRUE, 'removeNewlines' => TRUE ) );
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -1610,24 +1642,39 @@ abstract class _Model extends \IPS\Patterns\ActiveRecord
|
||||
* @brief Constant allow anonymous comments
|
||||
*/
|
||||
const ANON_COMMENTS = 2;
|
||||
|
||||
|
||||
/**
|
||||
* [Node] Does the currently logged in user have permission to post anonymously in this node?
|
||||
*
|
||||
* @return bool
|
||||
* @param int $where What are we checking, 0 => means don't check it, 2 means comments only
|
||||
* @param \IPS\Member|NULL $member The member posting anonymously or NULL for logged in member
|
||||
* @return bool
|
||||
*/
|
||||
public function canPostAnonymously( $where = 0 )
|
||||
public function canPostAnonymously( $where = 0, \IPS\Member $member = NULL ): bool
|
||||
{
|
||||
if ( ! isset( static::$contentItemClass ) or ! \in_array( 'IPS\Content\Anonymous', class_implements( static::$contentItemClass ) ) )
|
||||
{
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if( ! \IPS\Member::loggedIn()->member_id or ! \IPS\Member::loggedIn()->group['gbw_can_post_anonymously'] )
|
||||
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
|
||||
if( ! $member->member_id or ! $member->group['gbw_can_post_anonymously'] )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return $this->isAnonymousContentSupported( $where );
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the current node support anonymous content?
|
||||
*
|
||||
* @param int $where What are we checking, 0 => means don't check it, 2 means comments only
|
||||
* @return bool
|
||||
*/
|
||||
public function isAnonymousContentSupported( int $where = 0 ) : bool
|
||||
{
|
||||
/* 1 means both items and comments */
|
||||
if ( $this->allow_anonymous === 1 )
|
||||
{
|
||||
@@ -1639,13 +1686,12 @@ abstract class _Model extends \IPS\Patterns\ActiveRecord
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* 2 means comments only */
|
||||
if ( $where === static::ANON_COMMENTS and $this->allow_anonymous === 2 )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -2206,6 +2252,16 @@ abstract class _Model extends \IPS\Patterns\ActiveRecord
|
||||
return $this->can( 'view', $member );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return if this node has custom permissions
|
||||
*
|
||||
* @return null|array
|
||||
*/
|
||||
public static function customPermissionNodes()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Cached permission checks
|
||||
*/
|
||||
@@ -3472,7 +3528,7 @@ abstract class _Model extends \IPS\Patterns\ActiveRecord
|
||||
protected static $deleteOrMoveQueue = NULL;
|
||||
|
||||
/**
|
||||
* Is this node currently queued for deleting or moving content?
|
||||
* Is this node currently queued for deleting or moving content OR is it the target of content queued to be moved from another node?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@@ -3500,6 +3556,15 @@ abstract class _Model extends \IPS\Patterns\ActiveRecord
|
||||
{
|
||||
$this->queued = TRUE;
|
||||
}
|
||||
elseif ( isset( $data['moveTo'] ) )
|
||||
{
|
||||
$moveToClass = $data['moveToClass'] ?? \get_class( $this );
|
||||
|
||||
if ( $moveToClass === \get_class( $this ) AND $data['moveTo'] == $this->_id )
|
||||
{
|
||||
$this->queued = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3687,6 +3752,11 @@ abstract class _Model extends \IPS\Patterns\ActiveRecord
|
||||
{
|
||||
$return['permissions'] = \in_array( 'IPS\Node\Permissions', class_implements( \get_class( $this ) ) ) ? $this->permissions() : NULL;
|
||||
}
|
||||
|
||||
if ( \IPS\IPS::classUsesTrait( \get_called_class(), 'IPS\Content\ClubContainer' ) AND $this->club() )
|
||||
{
|
||||
$return['public'] = ( $this->isPublic() ) ? 1 : 0;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
@@ -3710,4 +3780,74 @@ abstract class _Model extends \IPS\Patterns\ActiveRecord
|
||||
{
|
||||
return static::$nodeTitle . '_sg';
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Field cache for getDataLayerProperties
|
||||
*/
|
||||
protected $_dataLayerProperties = array();
|
||||
|
||||
/**
|
||||
* Get the properties that can be added to the datalayer for this key
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getDataLayerProperties()
|
||||
{
|
||||
if ( empty( $this->_dataLayerProperties ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$url = (string) $this->url();
|
||||
}
|
||||
catch ( \BadMethodCallException $e )
|
||||
{
|
||||
$url = null;
|
||||
}
|
||||
|
||||
/* Try to figure out the Node's app, its lang key will be the area */
|
||||
$area = "System";
|
||||
if ( static::$permApp )
|
||||
{
|
||||
$app = static::$permApp;
|
||||
}
|
||||
elseif ( !empty( static::$restrictions['app'] ) )
|
||||
{
|
||||
$app = static::$restrictions['app'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$class = \get_called_class();
|
||||
$matches = array();
|
||||
preg_match( '/IPS\\\\([a-z]+)\\\\/', $class, $matches );
|
||||
$app = $matches[1] ?? null;
|
||||
}
|
||||
|
||||
/* If we got a valid app (directory) name, try its language key */
|
||||
if ( $app )
|
||||
{
|
||||
$area = \IPS\Lang::load( \IPS\Lang::defaultLanguage() )->addToStack( "__app_$app" );
|
||||
}
|
||||
|
||||
/* Get the path */
|
||||
$type = static::$nodeTitle ?? 'container';
|
||||
$path = [
|
||||
array( 'type' => $type, 'id' => $this->_id, 'name' => $this->_title )
|
||||
];
|
||||
foreach ( $this->parents() as $parent )
|
||||
{
|
||||
$path[] = array( 'type' => $parent::$nodeTitle ?? 'container', 'id' => $parent->_id, 'name' => $parent->_title );
|
||||
}
|
||||
|
||||
$this->_dataLayerProperties = array(
|
||||
'content_area' => $area,
|
||||
'content_container_id' => $this->_id,
|
||||
'content_container_name' => $this->_title,
|
||||
'content_container_type' => $type,
|
||||
'content_container_url' => $url,
|
||||
'content_container_path' => array_reverse( $path ),
|
||||
);
|
||||
}
|
||||
return $this->_dataLayerProperties;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -87,6 +87,15 @@ trait Statistics
|
||||
if ( $reload )
|
||||
{
|
||||
$items = iterator_to_array( \IPS\Db::i()->select( 'map_item_id, map_member_id', 'core_item_member_map', array(array('map_class=?', $contentItemClass), array(\IPS\Db::i()->in( 'map_item_id', $inSet ) ) ) ) );
|
||||
$itemIds = [];
|
||||
|
||||
if ( \count( $items ) )
|
||||
{
|
||||
foreach ( $items as $row )
|
||||
{
|
||||
$itemIds[] = $row['map_item_id'];
|
||||
}
|
||||
}
|
||||
|
||||
if ( $itemIds )
|
||||
{
|
||||
@@ -223,7 +232,6 @@ trait Statistics
|
||||
$commentClass = $contentItemClass::$commentClass;
|
||||
$commentItemField = $commentClass::$databasePrefix . $commentClass::$databaseColumnMap['item'];
|
||||
$authorColumn = $commentClass::$databasePrefix . $commentClass::$databaseColumnMap['author'];
|
||||
$dateColumn = $commentClass::$databasePrefix . $commentClass::$databaseColumnMap['date'];
|
||||
$where = array();
|
||||
|
||||
$deleteWhere = array( array( \IPS\Db::i()->in( 'map_item_id', $inSet ) ) );
|
||||
@@ -258,9 +266,9 @@ trait Statistics
|
||||
$itemWhere[] = array( \IPS\Db::i()->in( $hiddenColumn, array( 0, 2 ) ) ); # We want approved comments but also comments hidden because the item is hidden
|
||||
}
|
||||
|
||||
$itemWhere[] = array( \IPS\Db::i()->in( $contentItemClass::$databaseColumnId, $inSet ) );
|
||||
$itemWhere[] = array( \IPS\Db::i()->in( $contentItemClass::$databasePrefix . $contentItemClass::$databaseColumnId, $inSet ) );
|
||||
|
||||
$insertFromSelect = \IPS\Db::i()->select( "'" . str_replace( '\\', '\\\\', $contentItemClass ) . "', `{$contentItemClass::$databaseColumnId}`, `{$itemAuthorColumn}`, `{$itemDateColumn}`" , $contentItemClass::$databaseTable, $itemWhere );
|
||||
$insertFromSelect = \IPS\Db::i()->select( "'" . str_replace( '\\', '\\\\', $contentItemClass ) . "', `{$contentItemClass::$databasePrefix}{$contentItemClass::$databaseColumnId}`, `{$itemAuthorColumn}`, `{$itemDateColumn}`" , $contentItemClass::$databaseTable, $itemWhere );
|
||||
\IPS\Db::i()->replace( 'core_item_member_map', $insertFromSelect, TRUE );
|
||||
}
|
||||
|
||||
@@ -283,8 +291,8 @@ trait Statistics
|
||||
|
||||
$where[] = array(\IPS\Db::i()->in( $commentItemField, $inSet ));
|
||||
|
||||
$insertFromSelect = \IPS\Db::i()->select( "'" . str_replace( '\\', '\\\\', $contentItemClass ) . "', `{$commentItemField}`, `{$authorColumn}`, `{$dateColumn}`", $commentClass::$databaseTable, $where, $dateColumn . ' ASC' );
|
||||
\IPS\Db::i()->replace( 'core_item_member_map', $insertFromSelect, TRUE );
|
||||
$insertFromSelect = \IPS\Db::i()->select( "DISTINCT `{$authorColumn}`, `{$commentItemField}`, UNIX_TIMESTAMP(), '" . str_replace( '\\', '\\\\', $contentItemClass ) . "'", $commentClass::$databaseTable, $where );
|
||||
\IPS\Db::i()->replace( 'core_item_member_map', [ 'map_member_id, map_item_id, map_latest_date, map_class', $insertFromSelect ], TRUE );
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user