Version 5.0.13
This commit is contained in:
1 parent
b89858b2ff
commit
5efe744c5f
1407 files changed
+69690
-30177
No files matched your search
@@ -18,7 +18,9 @@ use IPS\Db;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\IPS;
|
||||
use IPS\Member;
|
||||
use IPS\Node\Grouping;
|
||||
use IPS\Node\Model;
|
||||
use IPS\Node\NodeGroup;
|
||||
use IPS\Output;
|
||||
use IPS\Patterns\ActiveRecordIterator;
|
||||
use IPS\Request;
|
||||
@@ -67,6 +69,7 @@ class Node extends FormAbstract
|
||||
'noParentNodes' => 'Custom' // If a value is provided, subnodes of this class which have no parent node will be added into a pseudo-group with the title provided. e.g. custom packages in Nexus do not belong to any package group
|
||||
'autoPopulate' => FALSE // Whether or not to autopopulate children of root nodes (defaults to TRUE which means the children are loaded, use FALSE to only show the parent nodes by default until they are clicked on)
|
||||
'clubs' => TRUE, // If TRUE, will also show nodes inside clubs that the user can access. Defaults to FALSE.
|
||||
'nodeGroups' => FALSE, // If TRUE, will show node groups for easier selection. Defaults to FALSE.
|
||||
'maxResults' => 200, // Maximum number of nodes to load. NULL to load all nodes or FALSE to respect node class definition. Defaults to FALSE.
|
||||
);
|
||||
* @endcode
|
||||
@@ -91,6 +94,7 @@ class Node extends FormAbstract
|
||||
'noParentNodes' => NULL,
|
||||
'autoPopulate' => TRUE,
|
||||
'clubs' => FALSE,
|
||||
'nodeGroups' => FALSE,
|
||||
'maxResults' => FALSE,
|
||||
);
|
||||
|
||||
@@ -121,6 +125,11 @@ class Node extends FormAbstract
|
||||
$this->options['clubs'] = FALSE;
|
||||
}
|
||||
|
||||
if( $this->options['nodeGroups'] and ! ( IPS::classUsesTrait( $this->options['class'], Grouping::class ) and Member::loggedIn()->isModerator() ) )
|
||||
{
|
||||
$this->options['nodeGroups'] = false;
|
||||
}
|
||||
|
||||
/* Do we need to respect the node class's defined max results (which is the default)? */
|
||||
if( $this->options['maxResults'] === FALSE )
|
||||
{
|
||||
@@ -237,6 +246,13 @@ class Node extends FormAbstract
|
||||
Output::i()->sendOutput( Theme::i()->getTemplate( 'forms', 'core', 'global' )->nodeCascade( $results, TRUE, $selectable, $this->options['subnodes'], $this->options['togglePerm'], $this->options['toggleIds'], $disabledCallback, FALSE, NULL, $this->options['class'], $this->options['where'], $this->options['disabled'], NULL, array(), NULL, $this->options['togglePermPBR'], $this->options['toggleIdsOff'] ) );
|
||||
}
|
||||
}
|
||||
|
||||
/* Node Groups */
|
||||
$nodeGroups = null;
|
||||
if( $this->options['nodeGroups'] )
|
||||
{
|
||||
$nodeGroups = $nodeClass::availableNodeGroups();
|
||||
}
|
||||
|
||||
/* Get initial nodes */
|
||||
$nodes = array();
|
||||
@@ -303,30 +319,68 @@ class Node extends FormAbstract
|
||||
}
|
||||
|
||||
/* What is selected? */
|
||||
if ( $this->options['zeroVal'] !== NULL and $this->value === 0 )
|
||||
if ( $this->options['zeroVal'] !== NULL and !( $this->value instanceof Model ) and !is_array( $this->value ) and $this->value == 0 )
|
||||
{
|
||||
$selected = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
$selected = array();
|
||||
$mergeNodes = array();
|
||||
|
||||
if ( is_array( $this->value ) )
|
||||
{
|
||||
/* Check to make sure we don't have a node group selected and do not have permission to select node groups */
|
||||
foreach( $this->value as $index => $node )
|
||||
{
|
||||
if ( $node instanceof NodeGroup )
|
||||
{
|
||||
if ( ! $this->options['nodeGroups'] )
|
||||
{
|
||||
/* We don't, so all we can do is get the current node IDs and present them */
|
||||
foreach( $node->nodes() as $groupedNode )
|
||||
{
|
||||
if ( $groupedNode instanceof $nodeClass )
|
||||
{
|
||||
$mergeNodes[ $groupedNode->_id ] = $groupedNode;
|
||||
}
|
||||
}
|
||||
unset( $this->value[ $index ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( count( $mergeNodes ) )
|
||||
{
|
||||
$this->value = array_merge( $this->value, $mergeNodes );
|
||||
}
|
||||
|
||||
foreach ( $this->value as $node )
|
||||
{
|
||||
$title = str_replace( "'", "'", htmlspecialchars( $node->_title, ENT_QUOTES | ENT_DISALLOWED, 'UTF-8', false ) );
|
||||
|
||||
$selected[ !( $node instanceof $nodeClass ) ? "{$node->_id}.s" : $node->_id ] = array( 'title' => $title, 'parents' => array_values( array_map( function( $val ){
|
||||
$suffix = "";
|
||||
if( !( $node instanceof $nodeClass ) )
|
||||
{
|
||||
$suffix = ( $node instanceof NodeGroup ) ? ".g" : ".s";
|
||||
}
|
||||
|
||||
$selected[ "{$node->_id}{$suffix}" ] = array( 'title' => $title, 'parents' => array_values( array_map( function( $val ){
|
||||
return str_replace( "'", "'", htmlspecialchars( $val->_title, ENT_QUOTES | ENT_DISALLOWED, 'UTF-8', false ) );
|
||||
}, iterator_to_array( $node->parents() ) ) ) );
|
||||
}
|
||||
}
|
||||
elseif ( $this->value instanceof Model )
|
||||
{
|
||||
$suffix = "";
|
||||
if( !( $this->value instanceof $nodeClass ) )
|
||||
{
|
||||
$suffix = ( $this->value instanceof NodeGroup ) ? ".g" : ".s";
|
||||
}
|
||||
|
||||
$class = get_class( $this->value );
|
||||
$title = str_replace( "'", "'", htmlspecialchars( $this->value->_title, ENT_QUOTES | ENT_DISALLOWED, 'UTF-8', false ) );
|
||||
$selected[ !( $this->value instanceof $nodeClass ) ? "{$this->value->_id}.s" : $this->value->_id ] = array( 'title' => $title, 'parents' => array_values( array_map( function( $val ){
|
||||
$selected[ "{$this->value->_id}{$suffix}" ] = array( 'title' => $title, 'parents' => array_values( array_map( function( $val ){
|
||||
return str_replace( "'", "'", htmlspecialchars( $val->_title, ENT_QUOTES | ENT_DISALLOWED, 'UTF-8', false ) );
|
||||
}, iterator_to_array( $this->value->parents() ) ) ) );
|
||||
}
|
||||
@@ -348,7 +402,7 @@ class Node extends FormAbstract
|
||||
}
|
||||
|
||||
/* Display */
|
||||
return Theme::i()->getTemplate( 'forms', 'core', 'global' )->node( $this->name, $selected, $this->options['multiple'], $this->options['url'], $nodeClass::$nodeTitle, $nodes, $this->options['zeroVal'], $selectable, $this->options['subnodes'], $this->options['togglePerm'], $this->options['toggleIds'], $disabledCallback, $this->options['zeroValTogglesOn'], $this->options['zeroValTogglesOff'], $this->options['autoPopulate'], $children, $this->options['class'], $this->options['where'], is_array( $this->options['disabledIds'] ) ? $this->options['disabledIds'] : array(), $this->options['noParentNodes'], $noParentNodes, $this->options['clubs'], $this->options['togglePermPBR'], $this->options['toggleIdsOff'], $loadMoreLink );
|
||||
return Theme::i()->getTemplate( 'forms', 'core', 'global' )->node( $this->name, $selected, $this->options['multiple'], $this->options['url'], $nodeClass::$nodeTitle, $nodes, $this->options['zeroVal'], $selectable, $this->options['subnodes'], $this->options['togglePerm'], $this->options['toggleIds'], $disabledCallback, $this->options['zeroValTogglesOn'], $this->options['zeroValTogglesOff'], $this->options['autoPopulate'], $children, $this->options['class'], $this->options['where'], is_array( $this->options['disabledIds'] ) ? $this->options['disabledIds'] : array(), $this->options['noParentNodes'], $noParentNodes, $this->options['clubs'], $this->options['togglePermPBR'], $this->options['toggleIdsOff'], $loadMoreLink, $nodeGroups );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -398,7 +452,7 @@ class Node extends FormAbstract
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ( $depthLimit === NULL OR $depth < $depthLimit )
|
||||
{
|
||||
if ( !$totalLimit or ( ( $currentCount += $node->childrenCount( $showable, NULL, $this->options['subnodes'], $this->options['where'] ) ) < $totalLimit ) )
|
||||
@@ -463,25 +517,52 @@ class Node extends FormAbstract
|
||||
$showable = $this->_getShowable();
|
||||
|
||||
if ( $this->value and !( $this->value instanceof Model ) )
|
||||
{
|
||||
{
|
||||
$return = array();
|
||||
foreach ( is_array( $this->value ) ? $this->value : explode( ',', $this->value ) as $v )
|
||||
{
|
||||
if ( $v instanceof Model )
|
||||
{
|
||||
$return[ !( $v instanceof $nodeClass ) ? "s{$v->_id}" : $v->_id ] = $v;
|
||||
$prefix = '';
|
||||
if( !( $v instanceof $nodeClass ) )
|
||||
{
|
||||
$prefix = ( $v instanceof NodeGroup ) ? 'g' : 's';
|
||||
}
|
||||
$return [ $prefix . $v->_id ] = $v;
|
||||
}
|
||||
elseif( $v )
|
||||
{
|
||||
try
|
||||
{
|
||||
$exploded = explode( '.', $v );
|
||||
$classToUse = ( isset( $exploded[1] ) and $exploded[1] === 's' ) ? $nodeClass::$subnodeClass : $nodeClass;
|
||||
$node = $classToUse::load( $exploded[0] );
|
||||
|
||||
if ( ( !$showable or $node->can( $showable ) ) and !$selectable or ( is_string( $selectable ) and $node->can( $selectable ) ) or ( is_callable( $selectable ) and $selectable( $node ) ) )
|
||||
if( ( mb_substr( $v, 0, 1 ) === 'g' or mb_substr( $v, 0, 1 ) === 's' ) and is_numeric( mb_substr( $v, 1 ) ) )
|
||||
{
|
||||
$return[ isset( $exploded[1] ) ? "s{$node->_id}" : $node->_id ] = $node;
|
||||
$exploded = [
|
||||
mb_substr( $v, 1 ),
|
||||
mb_substr( $v, 0, 1 )
|
||||
];
|
||||
}
|
||||
else
|
||||
{
|
||||
$exploded = explode( '.', $v );
|
||||
}
|
||||
|
||||
if( isset( $exploded[1] ) )
|
||||
{
|
||||
$classToUse = ( $exploded[1] === 'g' ) ? NodeGroup::class : $nodeClass::$subnodeClass;
|
||||
}
|
||||
else
|
||||
{
|
||||
$classToUse = $nodeClass;
|
||||
}
|
||||
|
||||
$node = $classToUse::load( $exploded[0] );
|
||||
if( $classToUse == NodeGroup::class )
|
||||
{
|
||||
$return[ 'g' . $node->_id ] = $node;
|
||||
}
|
||||
elseif ( ( !$showable or $node->can( $showable ) ) and !$selectable or ( is_string( $selectable ) and $node->can( $selectable ) ) or ( is_callable( $selectable ) and $selectable( $node ) ) )
|
||||
{
|
||||
$return[ ( $exploded[1] ?? '' ) . $node->_id ] = $node;
|
||||
}
|
||||
}
|
||||
catch ( Exception $e ) {}
|
||||
|
||||
Reference in new issue
Block a user