Version 4.1.2

This commit is contained in:
Neo committed 2025-12-19 05:32:19 -08:00
1 parent 3ba79295ee
commit 28bd025b35
1131 files changed
+63658 -20579

No files matched your search

+218 -22
View File
@@ -199,6 +199,40 @@ abstract class _Model extends \IPS\Patterns\ActiveRecord
return static::$rootsResult[ $cacheKey ];
}
/**
* Get a count of all 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 mixed $where Additional WHERE clause
* @return array
*/
public static function countWhere( $permissionCheck='view', $member=NULL, $where=array() )
{
/* Permission check? */
$usingPermssions = ( in_array( 'IPS\Node\Permissions', class_implements( get_called_class() ) ) and $permissionCheck !== NULL );
if ( $usingPermssions )
{
$member = $member ?: \IPS\Member::loggedIn();
$where[] = array( '(' . \IPS\Db::i()->findInSet( 'core_permission_index.perm_' . static::$permissionMap[ $permissionCheck ], $member->groups ) . ' OR ' . 'core_permission_index.perm_' . static::$permissionMap[ $permissionCheck ] . '=? )', '*' );
if ( static::$databaseColumnEnabledDisabled )
{
$where[] = array( static::$databasePrefix . static::$databaseColumnEnabledDisabled . '=1' );
}
}
/* Select */
$select = \IPS\Db::i()->select( 'COUNT(*)', static::$databaseTable, $where );
if ( $usingPermssions )
{
$select->join( 'core_permission_index', array( "core_permission_index.app=? AND core_permission_index.perm_type=? AND core_permission_index.perm_type_id=" . static::$databaseTable . "." . static::$databasePrefix . static::$databaseColumnId, static::$permApp, static::$permType ) );
}
/* Return */
return $select->first();
}
/**
* Fetch All Root Nodes as array
*
@@ -216,6 +250,11 @@ abstract class _Model extends \IPS\Patterns\ActiveRecord
}
return $return;
}
/**
* @brief Cache for owned noded
*/
protected static $ownedNodesCache = array();
/**
* Fetch all nodes owned by a given user
@@ -242,9 +281,9 @@ abstract class _Model extends \IPS\Patterns\ActiveRecord
}
/* Check the cache first */
if( isset( static::$rootsResult[ md5( get_called_class() . $member->member_id ) ] ) )
if( isset( static::$ownedNodesCache[ md5( get_called_class() . $member->member_id . json_encode( $where ) ) ] ) )
{
return static::$rootsResult[ md5( get_called_class() . $member->member_id ) ];
return static::$ownedNodesCache[ md5( get_called_class() . $member->member_id . json_encode( $where ) ) ];
}
/* Specify the order */
@@ -280,10 +319,10 @@ abstract class _Model extends \IPS\Patterns\ActiveRecord
}
/* Set cache */
static::$rootsResult[ md5( get_called_class(). $member->member_id ) ] = $nodes;
static::$ownedNodesCache[ md5( get_called_class(). $member->member_id . json_encode( $where ) ) ] = $nodes;
/* Return */
return static::$rootsResult[ md5( get_called_class(). $member->member_id ) ];
return static::$ownedNodesCache[ md5( get_called_class(). $member->member_id . json_encode( $where ) ) ];
}
/**
@@ -405,10 +444,43 @@ abstract class _Model extends \IPS\Patterns\ActiveRecord
* Get URL
*
* @return \IPS\Http\Url
* @note Any nodes that have URLs (e.g. forums, gallery categories) should override this
*/
public function url()
{
if ( isset( static::$urlBase ) and isset( static::$urlTemplate ) and isset( static::$seoTitleColumn ) )
{
if( $this->_url === NULL )
{
$seoTitleColumn = static::$seoTitleColumn;
$this->_url = \IPS\Http\Url::internal( static::$urlBase . $this->_id, 'front', static::$urlTemplate, array( $this->$seoTitleColumn ) );
}
return $this->_url;
}
throw new \BadMethodCallException;
}
/**
* Columns needed to query for search result / stream view
*
* @return array
*/
public static function basicDataColumns()
{
return array( static::$databasePrefix . static::$databaseColumnId, static::$databasePrefix . static::$seoTitleColumn );
}
/**
* Get URL from index data
*
* @param array $indexData Data from the search index
* @param array $itemData Basic data about the item. Only includes columns returned by item::basicDataColumns()
* @param array|NULL $containerData Basic data about the author. Only includes columns returned by container::basicDataColumns()
* @return \IPS\Http\Url
*/
public static function urlFromIndexData( $indexData, $itemData, $containerData )
{
return \IPS\Http\Url::internal( static::$urlBase . $indexData['index_container_id'], 'front', static::$urlTemplate, array( $containerData[ static::$databasePrefix . static::$seoTitleColumn ] ) );
}
/* !Getters */
@@ -782,15 +854,6 @@ abstract class _Model extends \IPS\Patterns\ActiveRecord
*/
public function parent()
{
if( static::$databaseColumnParent !== NULL )
{
$parentColumn = static::$databaseColumnParent;
if( $this->$parentColumn !== static::$databaseColumnParentRootValue )
{
return static::load( $this->$parentColumn );
}
}
if ( isset( static::$parentNodeClass ) )
{
$parentNodeClass = static::$parentNodeClass;
@@ -801,6 +864,15 @@ abstract class _Model extends \IPS\Patterns\ActiveRecord
}
}
if( static::$databaseColumnParent !== NULL )
{
$parentColumn = static::$databaseColumnParent;
if( $this->$parentColumn !== static::$databaseColumnParentRootValue )
{
return static::load( $this->$parentColumn );
}
}
return NULL;
}
@@ -1562,6 +1634,17 @@ abstract class _Model extends \IPS\Patterns\ActiveRecord
return static::$_canOnAny[ $_key ];
}
/**
* Disabled permissions
* Allow node classes to define permissions that are unselectable in the permission matrix
*
* @return array array( {group_id} => array( 'read', 'view', 'perm_7' );
*/
public function disabledPermissions()
{
return array();
}
/**
* Permission Types
*
@@ -1909,7 +1992,114 @@ abstract class _Model extends \IPS\Patterns\ActiveRecord
return NULL;
}
}
/**
* Set the comment/approved/hidden counts
*
* @return void
*/
public function resetCommentCounts()
{
if ( !isset( static::$contentItemClass ) )
{
return false;
}
/* Update container */
$itemClass = static::$contentItemClass;
$idColumn = static::$databaseColumnId;
$itemIdColumn = $itemClass::$databaseColumnId;
$commentClass = $itemClass::$commentClass;
$commentIdColumn = $commentClass::$databaseColumnId;
$containerWhere = array( array( $itemClass::$databasePrefix . $itemClass::$databaseColumnMap['container'] . '=?', $this->_id ) );
$anyContainerWhere = $containerWhere;
if ( in_array( 'IPS\Content\Hideable', class_implements( $itemClass ) ) )
{
if ( isset( $itemClass::$databaseColumnMap['approved'] ) )
{
$containerWhere[] = array( $itemClass::$databasePrefix . $itemClass::$databaseColumnMap['approved'] . '=?', 1 );
}
elseif ( isset( $itemClass::$databaseColumnMap['hidden'] ) )
{
$containerWhere[] = array( $itemClass::$databasePrefix . $itemClass::$databaseColumnMap['hidden'] . '=?', 0 );
}
}
if ( $this->_items !== NULL )
{
$this->_items = \IPS\Db::i()->select( 'COUNT(*)', $itemClass::$databaseTable, $containerWhere )->first();
}
if ( $this->_comments !== NULL )
{
$commentWhere = array(
array( $commentClass::$databaseTable . '.' . $commentClass::$databasePrefix . $commentClass::$databaseColumnMap['item'] . ' = ' . $itemClass::$databaseTable . '.' . $itemClass::$databasePrefix . $itemIdColumn ),
array( $itemClass::$databaseTable . '.' . $itemClass::$databasePrefix . $itemClass::$databaseColumnMap['container'] . '=?', $this->_id )
);
if ( isset( $commentClass::$databaseColumnMap['approved'] ) )
{
$commentWhere[] = array( $commentClass::$databaseTable . '.' . $commentClass::$databasePrefix . $commentClass::$databaseColumnMap['approved'] . '=?', 1 );
}
elseif ( isset( $commentClass::$databaseColumnMap['hidden'] ) )
{
$commentWhere[] = array( $commentClass::$databaseTable . '.' . $commentClass::$databasePrefix . $commentClass::$databaseColumnMap['hidden'] . '=?', 0 );
}
$this->_comments = \IPS\Db::i()->select( 'COUNT(*)', array(
array( $commentClass::$databaseTable, $commentClass::$databaseTable ),
array( $itemClass::$databaseTable, $itemClass::$databaseTable )
), $commentWhere )->first();
}
if ( in_array( 'IPS\Content\Hideable', class_implements( $itemClass ) ) )
{
if ( $this->_unapprovedItems !== NULL )
{
$hiddenContainerWhere = array( array( $itemClass::$databasePrefix . $itemClass::$databaseColumnMap['container'] . '=?', $this->_id ) );
if ( isset( $itemClass::$databaseColumnMap['approved'] ) )
{
$hiddenContainerWhere[] = array( $itemClass::$databasePrefix . $itemClass::$databaseColumnMap['approved'] . '=?', 0 );
}
elseif ( isset( $itemClass::$databaseColumnMap['hidden'] ) )
{
$hiddenContainerWhere[] = array( $itemClass::$databasePrefix . $itemClass::$databaseColumnMap['hidden'] . '=?', 1 );
}
$this->_unapprovedItems = \IPS\Db::i()->select( 'COUNT(*)', $itemClass::$databaseTable, $hiddenContainerWhere )->first();
}
$commentWhere = array( array( $commentClass::$databaseTable . '.' . $commentClass::$databasePrefix . $commentClass::$databaseColumnMap['item'] . ' = ' . $itemClass::$databaseTable . '.' . $itemClass::$databasePrefix . $itemIdColumn ) );
if ( $this->_unapprovedComments !== NULL )
{
if ( $itemClass::$firstCommentRequired )
{
/* Only look in non-hidden items otherwise this count will be added to */
$commentWhere = array_merge( $commentWhere, $containerWhere );
}
else
{
$commentWhere = array_merge( $commentWhere, $anyContainerWhere );
}
if ( isset( $commentClass::$databaseColumnMap['approved'] ) )
{
$commentWhere[] = array( $commentClass::$databaseTable . '.' . $commentClass::$databasePrefix . $commentClass::$databaseColumnMap['approved'] . '=?', 0 );
}
elseif ( isset( $commentClass::$databaseColumnMap['hidden'] ) )
{
$commentWhere[] = array( $commentClass::$databaseTable . '.' . $commentClass::$databasePrefix . $commentClass::$databaseColumnMap['hidden'] . '=?', 1 );
}
$this->_unapprovedComments = \IPS\Db::i()->select( 'COUNT(*)', array(
array( $commentClass::$databaseTable, $commentClass::$databaseTable ),
array( $itemClass::$databaseTable, $itemClass::$databaseTable )
), $commentWhere )->first();
}
}
}
/**
* Retrieve content item count (if applicable) for a node.
*
@@ -2040,11 +2230,7 @@ abstract class _Model extends \IPS\Patterns\ActiveRecord
else
{
$where[] = array( $contentItemClass::$databaseTable . '.' . $contentItemClass::$databasePrefix . $contentItemClass::$databaseColumnMap['container'] . '=?', $this->$idColumn );
/* This is silly, but I encountered a very strange eaccelerator bug in ticket 922529 where concatenating the data caused
$contentItemClass::$databaseColumnMap['author'] to evaluate as $commentClass::$databaseColumnMap['author'], resulting in DB errors */
$contentItemColumn = $contentItemClass::$databaseTable . '.' . $contentItemClass::$databasePrefix . $contentItemClass::$databaseColumnMap['author'];
$where[] = array( '(' . $commentClass::$databaseTable . '.' . $commentClass::$databasePrefix . $commentClass::$databaseColumnMap['author'] . '=? OR ' . $contentItemColumn . '=?)', $member->member_id, $member->member_id );
$where[] = array( '(' . $commentClass::$databaseTable . '.' . $commentClass::$databasePrefix . $commentClass::$databaseColumnMap['author'] . '=? OR ' . $contentItemClass::$databaseTable . '.' . $contentItemClass::$databasePrefix . $contentItemClass::$databaseColumnMap['author'] . '=?)', $member->member_id, $member->member_id );
}
/* Distinct will trigger a temporary table, so only use it if we need it */
@@ -2063,7 +2249,7 @@ abstract class _Model extends \IPS\Patterns\ActiveRecord
$where[] = $additionalWhere;
}
$joinClause = array( $commentClass::$databasePrefix . $commentClass::$databaseColumnMap['item'] . '=' . $contentItemClass::$databasePrefix . $contentItemClass::$databaseColumnId );
$joinClause = array( $commentClass::$databasePrefix . $commentClass::$databaseColumnMap['item'] . '=' . $contentItemClass::$databaseTable . '.' . $contentItemClass::$databasePrefix . $contentItemClass::$databaseColumnId );
$items = \IPS\Db::i()->select( $contentItemClass::$databaseTable . '.' . $contentItemClass::$databasePrefix . $contentItemClass::$databaseColumnId, $contentItemClass::$databaseTable, $where, NULL, NULL, NULL, NULL, $distinct );
$items->join( $commentClass::$databaseTable, ( $commentJoinWhere !== NULL ) ? array( $joinClause, $commentJoinWhere ) : $joinClause );
@@ -2180,7 +2366,7 @@ abstract class _Model extends \IPS\Patterns\ActiveRecord
{
\IPS\Lang::saveCustom( ( static::$permApp !== NULL ) ? static::$permApp : 'core', static::$titleLangPrefix . $this->_id, iterator_to_array( \IPS\Db::i()->select( 'CONCAT(word_custom, \' ' . \IPS\Member::loggedIn()->language()->get('copy_noun') . '\') as word_custom, lang_id', 'core_sys_lang_words', array( 'word_key=?', static::$titleLangPrefix . $oldId ) )->setKeyField( 'lang_id' )->setValueField('word_custom') ) );
}
else
elseif ( method_exists( $this, 'get__title' ) and method_exists( $this, 'set__title' ) )
{
$this->_title = $this->_title . ' ' . \IPS\Member::loggedIn()->language()->get('copy_noun');
}
@@ -2196,7 +2382,7 @@ abstract class _Model extends \IPS\Patterns\ActiveRecord
$order = \IPS\Db::i()->select( array( "MAX( `" . static::$databasePrefix . static::$databaseColumnOrder . "` )" ), static::$databaseTable, array() )->first();
$this->$orderColumn = $order + 1;
}
$this->_items = 0;
$this->_comments = 0;
$this->_reviews = 0;
@@ -2710,4 +2896,14 @@ abstract class _Model extends \IPS\Patterns\ActiveRecord
{
return array( \IPS\Theme::i()->getTemplate( 'tables', 'core' ), 'nodeRows' );
}
/**
* Get template for managing this nodes follows
*
* @return callable
*/
public static function manageFollowNodeRow()
{
return array( \IPS\Theme::i()->getTemplate( 'tables', 'core' ), 'manageFollowNodeRow' );
}
}