Version 4.1.2
This commit is contained in:
1 parent
3ba79295ee
commit
28bd025b35
1131 files changed
+63658
-20579
No files matched your search
+206
-67
@@ -248,10 +248,22 @@ abstract class _Content extends \IPS\Patterns\ActiveRecord
|
||||
*/
|
||||
public function truncated( $oneLine=FALSE )
|
||||
{
|
||||
/* Specifically remove quotes, and any scripts (which someone with HTML posting allowed may have legitimately enabled */
|
||||
$text = \IPS\Text\Parser::removeElements( $this->content(), array( 'blockquote', 'script' ) );
|
||||
|
||||
/* Convert headers and paragraphs into line breaks or just spaces */
|
||||
$text = str_replace( array( '</p>', '</h1>', '</h2>', '</h3>', '</h4>', '</h5>', '</h6>' ), ( $oneLine ? ' ' : '<br>' ), $text );
|
||||
$text = strip_tags( $text, '<br>' );
|
||||
|
||||
/* Add a space at the end of list items to prevent two list items from running into each other */
|
||||
$text = str_replace( '</li>', ' </li>', $text );
|
||||
|
||||
/* Remove all HTML apart from <br>s*/
|
||||
$text = strip_tags( $text, '<br>' );
|
||||
|
||||
/* Remove any <br>s from the start so there isn't just blank space at the top, but maintaining <br>s elsewhere */
|
||||
$text = preg_replace( '/^[(\s)(<br>)\x{00a0}]*/u', '', $text );
|
||||
|
||||
/* Return */
|
||||
return $text;
|
||||
}
|
||||
|
||||
@@ -419,7 +431,7 @@ abstract class _Content extends \IPS\Patterns\ActiveRecord
|
||||
isset( $containerClass::$modPerm )
|
||||
and
|
||||
(
|
||||
$member->modPermission( $containerClass::$modPerm ) === 0
|
||||
$member->modPermission( $containerClass::$modPerm ) === -1
|
||||
or
|
||||
(
|
||||
is_array( $member->modPermission( $containerClass::$modPerm ) )
|
||||
@@ -787,13 +799,15 @@ abstract class _Content extends \IPS\Patterns\ActiveRecord
|
||||
$index->save();
|
||||
|
||||
/* Create a report */
|
||||
\IPS\Db::i()->insert( 'core_rc_reports', array(
|
||||
$reportInsert = array(
|
||||
'rid' => $index->id,
|
||||
'report' => $reportContent,
|
||||
'report_by' => (int) \IPS\Member::loggedIn()->member_id,
|
||||
'date_reported' => time(),
|
||||
'ip_address' => \IPS\Request::i()->ipAddress()
|
||||
) );
|
||||
);
|
||||
|
||||
\IPS\Db::i()->insert( 'core_rc_reports', $reportInsert );
|
||||
|
||||
|
||||
/* Rebuild */
|
||||
@@ -822,7 +836,7 @@ abstract class _Content extends \IPS\Patterns\ActiveRecord
|
||||
$moderators[ $mod['type'] ][] = $mod['id'];
|
||||
}
|
||||
}
|
||||
$notification = new \IPS\Notification( \IPS\Application::load('core'), 'report_center', $index, array( $index, $reportContent, $this ) );
|
||||
$notification = new \IPS\Notification( \IPS\Application::load('core'), 'report_center', $index, array( $index, $reportInsert, $this ) );
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_members', ( count( $moderators['m'] ) ? \IPS\Db::i()->in( 'member_id', $moderators['m'] ) . ' OR ' : '' ) . \IPS\Db::i()->in( 'member_group_id', $moderators['g'] ) . ' OR ' . \IPS\Db::i()->findInSet( 'mgroup_others', $moderators['g'] ) ) as $member )
|
||||
{
|
||||
$notification->recipients->attach( \IPS\Member::constructFromData( $member ) );
|
||||
@@ -871,13 +885,93 @@ abstract class _Content extends \IPS\Patterns\ActiveRecord
|
||||
/**
|
||||
* Get HTML for search result display
|
||||
*
|
||||
* @return callable
|
||||
* @param array $indexData Data from the search index
|
||||
* @param array $authorData Basic data about the author. Only includes columns returned by \IPS\Member::columnsForPhoto()
|
||||
* @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()
|
||||
* @param array $reputationData Array of people who have given reputation and the reputation they gave
|
||||
* @param int|NULL $reviewRating If this is a review, the rating
|
||||
* @param bool $iPostedIn If the user has posted in the item
|
||||
* @param string $view 'expanded' or 'condensed'
|
||||
* @param bool $asItem Displaying results as items?
|
||||
* @return string
|
||||
*/
|
||||
public function activityStreamHtml()
|
||||
public static function searchResult( array $indexData, array $authorData, array $itemData, array $containerData = NULL, array $reputationData, $reviewRating, $iPostedIn, $view, $asItem )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'system', 'core', 'front' )->activityStreamResult( $this );
|
||||
/* Item details */
|
||||
$itemClass = $indexData['index_class'];
|
||||
if ( in_array( 'IPS\Content\Comment', class_parents( get_called_class() ) ) )
|
||||
{
|
||||
$itemClass = static::$itemClass;
|
||||
$unread = $itemClass::unreadFromData( NULL, $indexData['index_date_updated'], $indexData['index_date_created'], $indexData['index_item_id'], $indexData['index_container_id'], FALSE );
|
||||
}
|
||||
else
|
||||
{
|
||||
$unread = static::unreadFromData( NULL, $indexData['index_date_updated'], $indexData['index_date_created'], $indexData['index_item_id'], $indexData['index_container_id'], FALSE );
|
||||
}
|
||||
$itemUrl = $itemClass::urlFromIndexData( $indexData, $itemData );
|
||||
|
||||
/* Object URL */
|
||||
$indefiniteArticle = static::_indefiniteArticle( $containerData );
|
||||
if ( in_array( 'IPS\Content\Comment', class_parents( get_called_class() ) ) )
|
||||
{
|
||||
if ( in_array( 'IPS\Content\Review', class_parents( get_called_class() ) ) )
|
||||
{
|
||||
$objectUrl = $itemUrl->setQueryString( array( 'do' => 'findReview', 'review' => $indexData['index_object_id'] ) );
|
||||
$showRepUrl = $itemUrl->setQueryString( array( 'do' => 'showRepReview', 'review' => $indexData['index_object_id'] ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$objectUrl = $itemUrl->setQueryString( array( 'do' => 'findComment', 'comment' => $indexData['index_object_id'] ) );
|
||||
$showRepUrl = $itemUrl->setQueryString( array( 'do' => 'showRepComment', 'comment' => $indexData['index_object_id'] ) );
|
||||
}
|
||||
|
||||
$indefiniteArticle = $itemClass::_indefiniteArticle( $containerData );
|
||||
}
|
||||
else
|
||||
{
|
||||
$objectUrl = $itemUrl;
|
||||
$showRepUrl = $itemUrl->setQueryString( 'do', 'showRep' );
|
||||
}
|
||||
$articles = array( 'indefinite' => $indefiniteArticle, 'definite' => \IPS\Member::loggedIn()->language()->addToStack( $itemClass::$title, FALSE, array( 'strtolower' => TRUE ) ) );
|
||||
|
||||
/* Container details */
|
||||
$containerUrl = NULL;
|
||||
$containerTitle = NULL;
|
||||
if ( isset( $itemClass::$containerNodeClass ) )
|
||||
{
|
||||
$containerClass = $itemClass::$containerNodeClass;
|
||||
$containerTitle = \IPS\Member::loggedIn()->language()->addToStack( $containerClass::$titleLangPrefix . $indexData['index_container_id'] );
|
||||
$containerUrl = $containerClass::urlFromIndexData( $indexData, $itemData, $containerData );
|
||||
}
|
||||
|
||||
/* Reputation */
|
||||
$repCount = array_sum( $reputationData );
|
||||
|
||||
/* Snippet */
|
||||
$snippet = static::searchResultSnippet( $indexData, $authorData, $itemData, $containerData, $reputationData, $reviewRating, $view );
|
||||
|
||||
/* Return */
|
||||
return \IPS\Theme::i()->getTemplate( 'system', 'core', 'front' )->searchResult( $indexData, $articles, $authorData, $itemData, $unread, $asItem ? $itemUrl : $objectUrl, $itemUrl, $containerUrl, $containerTitle, $repCount, $showRepUrl, $snippet, $iPostedIn, $view );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get snippet HTML for search result display
|
||||
*
|
||||
* @param array $indexData Data from the search index
|
||||
* @param array $authorData Basic data about the author. Only includes columns returned by \IPS\Member::columnsForPhoto()
|
||||
* @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()
|
||||
* @param array $reputationData Array of people who have given reputation and the reputation they gave
|
||||
* @param int|NULL $reviewRating If this is a review, the rating
|
||||
* @param string $view 'expanded' or 'condensed'
|
||||
* @return callable
|
||||
*/
|
||||
public static function searchResultSnippet( array $indexData, array $authorData, array $itemData, array $containerData = NULL, array $reputationData, $reviewRating, $view )
|
||||
{
|
||||
return $view == 'expanded' ? \IPS\Theme::i()->getTemplate( 'system', 'core', 'front' )->searchResultSnippet( $indexData ) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the filters that are available for selecting table rows
|
||||
*
|
||||
@@ -938,59 +1032,85 @@ abstract class _Content extends \IPS\Patterns\ActiveRecord
|
||||
*/
|
||||
public function canGiveReputation( $type, \IPS\Member $member = NULL )
|
||||
{
|
||||
if ( \IPS\Member::loggedIn()->member_id and \IPS\Settings::i()->reputation_enabled and !in_array( $this->author()->member_group_id, explode( ',', \IPS\Settings::i()->reputation_protected_groups ) ) and $this instanceof \IPS\Content\Reputation )
|
||||
{
|
||||
/* Can we rep ourselves? */
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
if ( $this->author() == $member and !\IPS\Settings::i()->reputation_can_self_vote )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Are we allowed to give reputation at all? - We still need to allow users to undo rep they have given */
|
||||
$limit = ( $type === 1 ) ? $member->group['g_rep_max_positive'] : $member->group['g_rep_max_negative'];
|
||||
if ( $limit == 0 and !$this->repGiven( $member ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Protected Groups */
|
||||
if ( in_array( $this->author()->member_group_id, explode( ',', \IPS\Settings::i()->reputation_protected_groups ) ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Now work it out */
|
||||
switch ( \IPS\Settings::i()->reputation_point_types )
|
||||
{
|
||||
/* If we're using a positive system, we can rep positive only if we haven't repped yet, or negative only if we have */
|
||||
case 'like':
|
||||
case 'positive':
|
||||
return ( $this->repGiven( $member ) === 1 ) ? ( $type === -1 ) : ( $type === 1 );
|
||||
|
||||
/* If we're using a negative system, we can rep negative only if we haven't repped yet, or positive only if we have */
|
||||
case 'negative':
|
||||
return $this->repGiven( $member ) ? ( $type === 1 ) : ( $type === -1 );
|
||||
|
||||
/* If we're using a positive and negative system - it's more complicated... */
|
||||
case 'both':
|
||||
switch ( $this->repGiven( $member ) )
|
||||
{
|
||||
/* If we haven't repped yet, we can do either */
|
||||
case 0:
|
||||
return TRUE;
|
||||
|
||||
/* If we've given positive rep already, we can only do negative now */
|
||||
case 1:
|
||||
return ( $type === -1 );
|
||||
|
||||
/* If we've given negative rep already, we can only do positive now */
|
||||
case -1:
|
||||
return ( $type === 1 );
|
||||
}
|
||||
}
|
||||
return static::_canGiveReputation( $type, $this->author()->member_id, $this->author()->member_group_id, $this->repGiven( $member ), $member );
|
||||
}
|
||||
|
||||
/**
|
||||
* Can give reputation?
|
||||
*
|
||||
* @note This method is also ran to check if a member can "unrep"
|
||||
* @param int $type 1 for positive, -1 for negative
|
||||
* @param int $authorId The author ID
|
||||
* @param int $authorGroup The author group
|
||||
* @param int $repGiven The reputation we have already given (1 = positive, -1 = negative, 0 = no rep given)
|
||||
* @param \IPS\Member|NULL $member The member to check for (NULL for currently logged in member)
|
||||
* @return bool
|
||||
*/
|
||||
public static function _canGiveReputation( $type, $authorId, $authorGroup, $repGiven, \IPS\Member $member = NULL )
|
||||
{
|
||||
/* Reputation needs to be enabled */
|
||||
if ( !\IPS\Settings::i()->reputation_enabled or !in_array( 'IPS\Content\Reputation', class_implements( get_called_class() ) ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Guests cannot rep */
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
if ( !$member->member_id )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Author needs to not be protected */
|
||||
if ( in_array( $authorGroup, explode( ',', \IPS\Settings::i()->reputation_protected_groups ) ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Users may not be able to rep themselves */
|
||||
if ( !\IPS\Settings::i()->reputation_can_self_vote and $authorId == $member->member_id )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Rep per day */
|
||||
$limit = ( $type === 1 ) ? $member->group['g_rep_max_positive'] : $member->group['g_rep_max_negative'];
|
||||
if ( $limit == 0 and !$repGiven )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Have we already given rep? */
|
||||
switch ( \IPS\Settings::i()->reputation_point_types )
|
||||
{
|
||||
/* If we're using a positive system, we can rep positive only if we haven't repped yet, or negative only if we have */
|
||||
case 'like':
|
||||
case 'positive':
|
||||
return ( $repGiven === 1 ) ? ( $type === -1 ) : ( $type === 1 );
|
||||
|
||||
/* If we're using a negative system, we can rep negative only if we haven't repped yet, or positive only if we have */
|
||||
case 'negative':
|
||||
return $repGiven ? ( $type === 1 ) : ( $type === -1 );
|
||||
|
||||
/* If we're using a positive and negative system - it's more complicated... */
|
||||
case 'both':
|
||||
switch ( $repGiven )
|
||||
{
|
||||
/* If we haven't repped yet, we can do either */
|
||||
case 0:
|
||||
return TRUE;
|
||||
|
||||
/* If we've given positive rep already, we can only do negative now */
|
||||
case 1:
|
||||
return ( $type === -1 );
|
||||
|
||||
/* If we've given negative rep already, we can only do positive now */
|
||||
case -1:
|
||||
return ( $type === 1 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Catch all */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1028,13 +1148,15 @@ abstract class _Content extends \IPS\Patterns\ActiveRecord
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
$limit = ( $type === 1 ) ? $member->group['g_rep_max_positive'] : $member->group['g_rep_max_negative'];
|
||||
|
||||
if ( $limit !== 999 )
|
||||
{
|
||||
$count = \IPS\Db::i()->select( 'COUNT(*)', 'core_reputation_index', array( 'member_id=? AND rep_date>?', $member->member_id, \IPS\DateTime::create()->sub( new \DateInterval( 'P1D' ) )->getTimestamp() ) )->first();
|
||||
$count = \IPS\Db::i()->select( 'COUNT(*)', 'core_reputation_index', array( 'member_id=? AND rep_date>? AND rep_rating=?', $member->member_id, \IPS\DateTime::create()->sub( new \DateInterval( 'P1D' ) )->getTimestamp(), $type ) )->first();
|
||||
if ( $count >= $limit )
|
||||
{
|
||||
throw new \DomainException( \IPS\Member::loggedIn()->language()->addToStack('rep_daily_exceeded', FALSE, array( 'sprintf' => array( $limit ) ) ) );
|
||||
throw new \DomainException( \IPS\Member::loggedIn()->language()->addToStack( \IPS\Settings::i()->reputation_point_types == 'like' ? 'rep_daily_exceeded_likes' :'rep_daily_exceeded', FALSE, array( 'sprintf' => array( $limit ) ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1049,7 +1171,7 @@ abstract class _Content extends \IPS\Patterns\ActiveRecord
|
||||
) );
|
||||
|
||||
/* Send Notification */
|
||||
if ( $type === 1 AND $this->author()->member_id AND $this->author() != \IPS\Member::loggedIn() )
|
||||
if ( $type === 1 AND $this->author()->member_id AND $this->author() != \IPS\Member::loggedIn() AND $this->canView( $this->author() ) )
|
||||
{
|
||||
$notification = new \IPS\Notification( \IPS\Application::load('core'), 'new_likes', $this, array( $this, \IPS\Member::loggedIn() ) );
|
||||
$notification->recipients->attach( $this->author() );
|
||||
@@ -1186,7 +1308,7 @@ abstract class _Content extends \IPS\Patterns\ActiveRecord
|
||||
{
|
||||
/* 3 random names */
|
||||
$idColumn = static::$databaseColumnId;
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_reputation_index', array( 'app=? AND type=? AND type_id=? AND member_id!=?', static::$application, static::$reputationType, $this->$idColumn, ( \IPS\Member::loggedIn()->member_id ) ?: 0 ), 'RAND()', 3 ) as $rep )
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_reputation_index', array( 'app=? AND type=? AND type_id=? AND member_id!=? AND rep_rating=?', static::$application, static::$reputationType, $this->$idColumn, ( \IPS\Member::loggedIn()->member_id ) ?: 0, 1 ), 'RAND()', 3 ) as $rep )
|
||||
{
|
||||
$people[] = \IPS\Theme::i()->getTemplate( 'global', 'core' )->userLink( \IPS\Member::load( $rep['member_id'] ) );
|
||||
$reputation--;
|
||||
@@ -1267,7 +1389,7 @@ abstract class _Content extends \IPS\Patterns\ActiveRecord
|
||||
const FOLLOW_PUBLIC = 1;
|
||||
const FOLLOW_ANONYMOUS = 2;
|
||||
|
||||
const NOTIFICATIONS_PER_BATCH = 100;
|
||||
const NOTIFICATIONS_PER_BATCH = 50;
|
||||
|
||||
/**
|
||||
* Send notifications
|
||||
@@ -1548,13 +1670,18 @@ abstract class _Content extends \IPS\Patterns\ActiveRecord
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( isset( $class::$commentClass ) )
|
||||
|
||||
if ( !( $member instanceof \IPS\Member ) )
|
||||
{
|
||||
$member = $member ? \IPS\Member::loggedIn() : NULL;
|
||||
}
|
||||
|
||||
if ( isset( $class::$commentClass ) and $class::supportsComments( $member ) )
|
||||
{
|
||||
$classes[] = $class::$commentClass;
|
||||
}
|
||||
|
||||
if ( isset( $class::$reviewClass ) )
|
||||
if ( isset( $class::$reviewClass ) and $class::supportsReviews( $member ) )
|
||||
{
|
||||
$classes[] = $class::$reviewClass;
|
||||
}
|
||||
@@ -1610,6 +1737,18 @@ abstract class _Content extends \IPS\Patterns\ActiveRecord
|
||||
* @return string
|
||||
*/
|
||||
public function indefiniteArticle( \IPS\Lang $lang = NULL )
|
||||
{
|
||||
$container = ( $this instanceof \IPS\Content\Comment ) ? $this->item()->containerWrapper() : $this->containerWrapper();
|
||||
return static::_indefiniteArticle( $container ? $container->_data : array(), $lang );
|
||||
}
|
||||
|
||||
/**
|
||||
* Indefinite Article
|
||||
*
|
||||
* @param \IPS\Lang|NULL $language The language to use, or NULL for the language of the currently logged in member
|
||||
* @return string
|
||||
*/
|
||||
public static function _indefiniteArticle( array $containerData = NULL, \IPS\Lang $lang = NULL )
|
||||
{
|
||||
$lang = $lang ?: \IPS\Member::loggedIn()->language();
|
||||
return $lang->addToStack( '__indefart_' . static::$title, FALSE );
|
||||
|
||||
Reference in new issue
Block a user