Version 4.2.0
This commit is contained in:
1 parent
0dc2aee5ed
commit
96997ddd8e
2074 files changed
+125454
-55780
No files matched your search
@@ -1,12 +1,11 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Content Filter for Search Queries
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community Suite
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) Invision Power Services, Inc.
|
||||
* @license https://www.invisioncommunity.com/legal/standards/
|
||||
* @package Invision Community
|
||||
* @since 6 Jul 2015
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\Content\Search;
|
||||
@@ -32,6 +31,12 @@ class _ContentFilter
|
||||
* @brief Classes to include
|
||||
*/
|
||||
public $classes = array();
|
||||
|
||||
/**
|
||||
* @brief Container classes to include
|
||||
* @note NULL means not to filter by container classes
|
||||
*/
|
||||
public $containerClasses = NULL;
|
||||
|
||||
/**
|
||||
* @brief Container ID filter
|
||||
@@ -85,7 +90,7 @@ class _ContentFilter
|
||||
* @param bool $includeItems Include items in results?
|
||||
* @param bool $includeComments Include comments in results?
|
||||
* @param bool $includeReviews Include reviews in results?
|
||||
* @return \IPS\Content\Search\ContainerFilter
|
||||
* @return \IPS\Content\Search\ContentFilter
|
||||
*/
|
||||
public static function init( $itemClass, $includeItems=TRUE, $includeComments=TRUE, $includeReviews=TRUE )
|
||||
{
|
||||
@@ -114,7 +119,7 @@ class _ContentFilter
|
||||
* Only include results in containers
|
||||
*
|
||||
* @param array $ids Acceptable container IDs
|
||||
* @return \IPS\Content\Search\ContainerFilter (for daisy chaining)
|
||||
* @return \IPS\Content\Search\ContentFilter (for daisy chaining)
|
||||
*/
|
||||
public function onlyInContainers( array $ids )
|
||||
{
|
||||
@@ -128,7 +133,7 @@ class _ContentFilter
|
||||
* Exclude results in containers
|
||||
*
|
||||
* @param array $ids Acceptable container IDs
|
||||
* @return \IPS\Content\Search\ContainerFilter (for daisy chaining)
|
||||
* @return \IPS\Content\Search\ContentFilter (for daisy chaining)
|
||||
*/
|
||||
public function excludeInContainers( array $ids )
|
||||
{
|
||||
@@ -142,7 +147,7 @@ class _ContentFilter
|
||||
* Only include results in items
|
||||
*
|
||||
* @param array $ids Acceptable item IDs
|
||||
* @return \IPS\Content\Search\ContainerFilter (for daisy chaining)
|
||||
* @return \IPS\Content\Search\ContentFilter (for daisy chaining)
|
||||
*/
|
||||
public function onlyInItems( array $ids )
|
||||
{
|
||||
@@ -156,7 +161,7 @@ class _ContentFilter
|
||||
* Exclude results in items
|
||||
*
|
||||
* @param array $ids Acceptable container IDs
|
||||
* @return \IPS\Content\Search\ContainerFilter (for daisy chaining)
|
||||
* @return \IPS\Content\Search\ContentFilter (for daisy chaining)
|
||||
*/
|
||||
public function excludeInItems( array $ids )
|
||||
{
|
||||
@@ -170,7 +175,7 @@ class _ContentFilter
|
||||
* Set minimum number of comments
|
||||
*
|
||||
* @param int $minimumComments The minimum number of comments
|
||||
* @return \IPS\Content\Search\ContainerFilter (for daisy chaining)
|
||||
* @return \IPS\Content\Search\ContentFilter (for daisy chaining)
|
||||
*/
|
||||
public function minimumComments( $minimumComments )
|
||||
{
|
||||
@@ -183,7 +188,7 @@ class _ContentFilter
|
||||
* Set minimum number of reviews
|
||||
*
|
||||
* @param int $minimumReviews The minimum number of reviews
|
||||
* @return \IPS\Content\Search\ContainerFilter (for daisy chaining)
|
||||
* @return \IPS\Content\Search\ContentFilter (for daisy chaining)
|
||||
*/
|
||||
public function minimumReviews( $minimumReviews )
|
||||
{
|
||||
@@ -196,7 +201,7 @@ class _ContentFilter
|
||||
* Set minimum number of views
|
||||
*
|
||||
* @param int $minimumViews The minimum number of views
|
||||
* @return \IPS\Content\Search\ContainerFilter (for daisy chaining)
|
||||
* @return \IPS\Content\Search\ContentFilter (for daisy chaining)
|
||||
*/
|
||||
public function minimumViews( $minimumViews )
|
||||
{
|
||||
@@ -208,7 +213,7 @@ class _ContentFilter
|
||||
/**
|
||||
* Only include results which are the first comment on an item requiring a comment
|
||||
*
|
||||
* @return \IPS\Content\Search\ContainerFilter (for daisy chaining)
|
||||
* @return \IPS\Content\Search\ContentFilter (for daisy chaining)
|
||||
*/
|
||||
public function onlyFirstComment()
|
||||
{
|
||||
@@ -220,7 +225,7 @@ class _ContentFilter
|
||||
/**
|
||||
* Only include results which are the last comment on an item requiring a comment
|
||||
*
|
||||
* @return \IPS\Content\Search\ContainerFilter (for daisy chaining)
|
||||
* @return \IPS\Content\Search\ContentFilter (for daisy chaining)
|
||||
*/
|
||||
public function onlyLastComment()
|
||||
{
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Abstract Search Index
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community Suite
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) Invision Power Services, Inc.
|
||||
* @license https://www.invisioncommunity.com/legal/standards/
|
||||
* @package Invision Community
|
||||
* @since 21 Aug 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\Content\Search;
|
||||
@@ -250,12 +249,32 @@ abstract class _Index extends \IPS\Patterns\Singleton
|
||||
catch ( \Exception $e ) { }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Club */
|
||||
$container = NULL;
|
||||
$containerId = NULL;
|
||||
$clubId = NULL;
|
||||
if ( $object instanceof \IPS\Content\Item )
|
||||
{
|
||||
$containerId = (int) $object->searchIndexContainer();
|
||||
$container = $object->containerWrapper();
|
||||
}
|
||||
else
|
||||
{
|
||||
$containerId = (int) $object->item()->mapped('container');
|
||||
$container = $object->item()->containerWrapper();
|
||||
}
|
||||
if ( $container and \IPS\IPS::classUsesTrait( $container, 'IPS\Content\ClubContainer' ) )
|
||||
{
|
||||
$clubId = $container->{$container::clubIdColumn()};
|
||||
}
|
||||
|
||||
/* Return */
|
||||
return array(
|
||||
'index_class' => $class,
|
||||
'index_object_id' => $object->$idColumn,
|
||||
'index_item_id' => ( $object instanceof \IPS\Content\Item ) ? $object->$idColumn : $object->mapped('item'),
|
||||
'index_container_class' => ( $object instanceof \IPS\Content\Item ) ? get_class( $object->searchIndexContainerClass() ) : get_class( $object->item()->searchIndexContainerClass() ),
|
||||
'index_container_id' => ( $object instanceof \IPS\Content\Item ) ? (int) $object->searchIndexContainer() : (int) $object->item()->mapped('container'),
|
||||
'index_title' => $title,
|
||||
'index_content' => $content,
|
||||
@@ -268,7 +287,8 @@ abstract class _Index extends \IPS\Patterns\Singleton
|
||||
'index_hidden' => $hiddenStatus,
|
||||
'index_item_index_id' => $itemIndexId,
|
||||
'index_item_author' => intval( ( $object instanceof \IPS\Content\Item ) ? $object->mapped('author') : $object->item()->mapped('author') ),
|
||||
'index_is_last_comment' => $isLastComment
|
||||
'index_is_last_comment' => $isLastComment,
|
||||
'index_club_id' => $clubId
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief MySQL Search Index
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community Suite
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) Invision Power Services, Inc.
|
||||
* @license https://www.invisioncommunity.com/legal/standards/
|
||||
* @package Invision Community
|
||||
* @since 21 Aug 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\Content\Search\Mysql;
|
||||
@@ -331,7 +330,7 @@ class _Index extends \IPS\Content\Search\Index
|
||||
$where[] = array( 'index_container_id=?', $containerId );
|
||||
}
|
||||
|
||||
\IPS\Db::i()->delete( 'core_search_index_item_map', array( 'index_item_id IN( ? )', \IPS\Db::i()->select( 'index_item_id', 'core_search_index', $where ) ) );
|
||||
\IPS\Db::i()->delete( 'core_search_index_item_map', array( 'index_class=? and index_item_id IN( ? )', $class, \IPS\Db::i()->select( 'index_item_id', 'core_search_index', $where ) ) );
|
||||
\IPS\Db::i()->delete( 'core_search_index_tags', array( 'index_id IN( ? )', \IPS\Db::i()->select( 'index_id', 'core_search_index', $where ) ) );
|
||||
\IPS\Db::i()->delete( 'core_search_index', $where );
|
||||
}
|
||||
@@ -375,6 +374,18 @@ class _Index extends \IPS\Content\Search\Index
|
||||
if ( $newContainer )
|
||||
{
|
||||
$update['index_container_id'] = $newContainer;
|
||||
|
||||
if ( $itemClass = ( in_array( 'IPS\Content\Item', class_parents( $class ) ) ? $class : $class::$itemClass ) and $containerClass = $itemClass::$containerNodeClass and \IPS\IPS::classUsesTrait( $containerClass, 'IPS\Content\ClubContainer' ) and $clubIdColumn = $containerClass::clubIdColumn() )
|
||||
{
|
||||
try
|
||||
{
|
||||
$update['index_club_id'] = $containerClass::load( $newContainer )->$clubIdColumn;
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
$update['index_club_id'] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( $newItemId )
|
||||
{
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief MySQL Search Query
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community Suite
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) Invision Power Services, Inc.
|
||||
* @license https://www.invisioncommunity.com/legal/standards/
|
||||
* @package Invision Community
|
||||
* @since 21 Aug 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\Content\Search\Mysql;
|
||||
@@ -128,6 +127,12 @@ class _Query extends \IPS\Content\Search\Query
|
||||
$clause[] = \IPS\Db::i()->in( 'index_container_id', $unsearchableIds, TRUE );
|
||||
}
|
||||
}
|
||||
|
||||
/* Are we excluding certain container classes? */
|
||||
if( $filter->containerClasses !== NULL )
|
||||
{
|
||||
$clause[] = \IPS\Db::i()->in( 'index_container_class', $filter->containerClasses );
|
||||
}
|
||||
|
||||
/* Set the item IDs */
|
||||
if ( $filter->itemIdFilter !== NULL )
|
||||
@@ -209,7 +214,32 @@ class _Query extends \IPS\Content\Search\Query
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Filter by club
|
||||
*
|
||||
* @param \IPS\Member\Club|int|array|null $club The club, or array of club IDs, or NULL to exclude content from clubs
|
||||
* @return \IPS\Content\Search\Query (for daisy chaining)
|
||||
*/
|
||||
public function filterByClub( $club )
|
||||
{
|
||||
if ( $club === NULL )
|
||||
{
|
||||
$this->where[] = 'index_club_id IS NULL';
|
||||
}
|
||||
if ( is_array( $club ) )
|
||||
{
|
||||
$this->where[] = array( \IPS\Db::i()->in( 'index_club_id', $club ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->where[] = array( 'index_club_id=?', $club instanceof \IPS\Member\Club ? $club->id : $club );
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter for profile
|
||||
@@ -253,6 +283,37 @@ class _Query extends \IPS\Content\Search\Query
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter by container class
|
||||
*
|
||||
* @param array $classes Container classes to exclude from results.
|
||||
* @param array $exclude Content classes to exclude from the filter. For cases where multiple content classes may have the same container class
|
||||
* such as Gallery images, comments and reviews.
|
||||
* @return \IPS\Content\Search\Query (for daisy chaining)
|
||||
*/
|
||||
public function filterByContainerClasses( $classes=array(), $exclude=array() )
|
||||
{
|
||||
if( empty( $exclude ) )
|
||||
{
|
||||
$this->where[] = \IPS\Db::i()->in( 'index_container_class', $classes, TRUE );
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach( $classes as $i => $class )
|
||||
{
|
||||
$classes[$i] = "'" . \IPS\DB::i()->real_escape_string( $class ) . "'";
|
||||
}
|
||||
foreach( $exclude as $i => $class )
|
||||
{
|
||||
$exclude[$i] = "'" . \IPS\DB::i()->real_escape_string( $class ) . "'";
|
||||
}
|
||||
|
||||
$this->where[] = '( index_container_class NOT IN(' . implode( ',', $classes ) . ') OR index_class IN(' . implode( ',', $exclude ) . ') )';
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter by content the user follows
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Abstract Search Query
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community Suite
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) Invision Power Services, Inc.
|
||||
* @license https://www.invisioncommunity.com/legal/standards/
|
||||
* @package Invision Community
|
||||
* @since 21 Aug 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\Content\Search;
|
||||
@@ -46,7 +45,7 @@ abstract class _Query
|
||||
* Create new query
|
||||
*
|
||||
* @param \IPS\Member $member The member performing the search (NULL for currently logged in member)
|
||||
* @return \IPS\Content\Search
|
||||
* @return \IPS\Content\Search\Query
|
||||
*/
|
||||
public static function init( \IPS\Member $member = NULL )
|
||||
{
|
||||
@@ -108,6 +107,14 @@ abstract class _Query
|
||||
*/
|
||||
abstract public function filterByAuthor( $author );
|
||||
|
||||
/**
|
||||
* Filter by club
|
||||
*
|
||||
* @param \IPS\Member\Club|int|array $club The club, or array of club IDs
|
||||
* @return \IPS\Content\Search\Query (for daisy chaining)
|
||||
*/
|
||||
abstract public function filterByClub( $club );
|
||||
|
||||
/**
|
||||
* Filter for profile
|
||||
*
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Search Result from Index
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community Suite
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) Invision Power Services, Inc.
|
||||
* @license https://www.invisioncommunity.com/legal/standards/
|
||||
* @package Invision Community
|
||||
* @since 15 Sep 2015
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\Content\Search\Result;
|
||||
@@ -63,9 +62,10 @@ class _Content extends \IPS\Content\Search\Result
|
||||
* @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 array $reactions Reaction Data
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( array $indexData, array $authorData, array $itemData, array $containerData = NULL, array $reputationData, $reviewRating = NULL, $iPostedIn = FALSE )
|
||||
public function __construct( array $indexData, array $authorData, array $itemData, array $containerData = NULL, array $reputationData, $reviewRating = NULL, $iPostedIn = FALSE, $reactions=array() )
|
||||
{
|
||||
$this->createdDate = \IPS\DateTime::ts( $indexData['index_date_created'] );
|
||||
$this->lastUpdatedDate = \IPS\DateTime::ts( $indexData['index_date_updated'] );
|
||||
@@ -76,6 +76,7 @@ class _Content extends \IPS\Content\Search\Result
|
||||
$this->reputationData = $reputationData;
|
||||
$this->reviewRating = $reviewRating;
|
||||
$this->iPostedIn = $iPostedIn;
|
||||
$this->reactions = $reactions;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,7 +90,7 @@ class _Content extends \IPS\Content\Search\Result
|
||||
*/
|
||||
public function html( $view = 'expanded', $asItem = FALSE, $canIgnoreComments=FALSE, $template=NULL )
|
||||
{
|
||||
return call_user_func( array( $this->indexData['index_class'], 'searchResult' ), $this->indexData, $this->authorData, $this->itemData, $this->containerData, $this->reputationData, $this->reviewRating, $this->iPostedIn, $view, $asItem, $canIgnoreComments, $template );
|
||||
return call_user_func( array( $this->indexData['index_class'], 'searchResult' ), $this->indexData, $this->authorData, $this->itemData, $this->containerData, $this->reputationData, $this->reviewRating, $this->iPostedIn, $view, $asItem, $canIgnoreComments, $template, $this->reactions );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Search Result not from Index
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community Suite
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) Invision Power Services, Inc.
|
||||
* @license https://www.invisioncommunity.com/legal/standards/
|
||||
* @package Invision Community
|
||||
* @since 15 Sep 2015
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\Content\Search\Result;
|
||||
@@ -32,6 +31,11 @@ class _Custom extends \IPS\Content\Search\Result
|
||||
* @brief Image
|
||||
*/
|
||||
protected $image;
|
||||
|
||||
/**
|
||||
* @brief Data used for merging multiple extra items
|
||||
*/
|
||||
protected $mergeData;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@@ -39,14 +43,39 @@ class _Custom extends \IPS\Content\Search\Result
|
||||
* @param \IPS\DateTime $time The time for this result
|
||||
* @param string $html HTML to display
|
||||
* @param string|NULL $image HTML for image to display
|
||||
* @param string|NULL $mergeData Data for merging
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( \IPS\DateTime $time, $html, $image = NULL )
|
||||
public function __construct( \IPS\DateTime $time, $html, $image = NULL, $mergeData = NULL )
|
||||
{
|
||||
$this->createdDate = $time;
|
||||
$this->lastUpdatedDate = $time;
|
||||
$this->html = $html;
|
||||
$this->image = $image;
|
||||
$this->mergeData = array( $mergeData );
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge in new data
|
||||
*
|
||||
* @param string $html New HTML to merge in as a list
|
||||
* @param string|NULL $mergeData Data for merging
|
||||
* @return void
|
||||
*/
|
||||
public function mergeInData( $html, $mergeData = NULL )
|
||||
{
|
||||
$this->html = $html;
|
||||
$this->mergeData[] = $mergeData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data for merging
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMergeData()
|
||||
{
|
||||
return $this->mergeData ?: array();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Search Result
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community Suite
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) Invision Power Services, Inc.
|
||||
* @license https://www.invisioncommunity.com/legal/standards/
|
||||
* @package Invision Community
|
||||
* @since 15 Sep 2015
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\Content\Search;
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Search Results
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community Suite
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) Invision Power Services, Inc.
|
||||
* @license https://www.invisioncommunity.com/legal/standards/
|
||||
* @package Invision Community
|
||||
* @since 21 Aug 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\Content\Search;
|
||||
@@ -53,6 +52,11 @@ class _Results extends \ArrayIterator
|
||||
*/
|
||||
protected $reputationData = array();
|
||||
|
||||
/**
|
||||
* @brief Reaction Data
|
||||
*/
|
||||
protected $reactions = array();
|
||||
|
||||
/**
|
||||
* @brief Review Ratings
|
||||
*/
|
||||
@@ -139,7 +143,7 @@ class _Results extends \ArrayIterator
|
||||
}
|
||||
}
|
||||
|
||||
if ( in_array( 'IPS\Content\Reputation', class_implements( $result['index_class'] ) ) )
|
||||
if ( \IPS\IPS::classUsesTrait( $result['index_class'], 'IPS\Content\Reactable' ) )
|
||||
{
|
||||
$reputationIds[ $result['index_class'] ][ $result['index_object_id'] ] = $result['index_object_id'];
|
||||
}
|
||||
@@ -153,8 +157,13 @@ class _Results extends \ArrayIterator
|
||||
{
|
||||
$itemIndexIds[] = $result['index_item_index_id'];
|
||||
}
|
||||
|
||||
if ( $result['index_club_id'] )
|
||||
{
|
||||
$containersToLoad[ 'IPS\Member\Club' ][ $result['index_club_id'] ] = $result['index_club_id'];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Load item data */
|
||||
foreach ( $itemsToLoad as $itemClass => $itemIds )
|
||||
{
|
||||
@@ -162,7 +171,7 @@ class _Results extends \ArrayIterator
|
||||
{
|
||||
$this->itemData[ $itemClass ][ $itemId ] = $itemData;
|
||||
|
||||
if ( isset( $itemData[ $itemClass::$databasePrefix . $itemClass::$databaseColumnMap['author'] ] ) )
|
||||
if ( isset( $itemClass::$databaseColumnMap ) and isset( $itemData[ $itemClass::$databasePrefix . $itemClass::$databaseColumnMap['author'] ] ) )
|
||||
{
|
||||
$memberId = $itemData[ $itemClass::$databasePrefix . $itemClass::$databaseColumnMap['author'] ];
|
||||
$membersToLoad[ $memberId ] = $memberId;
|
||||
@@ -198,26 +207,23 @@ class _Results extends \ArrayIterator
|
||||
$binds = array();
|
||||
foreach ( $reputationIds as $class => $ids )
|
||||
{
|
||||
$clause[] = "( app=? AND type=? AND " . \IPS\Db::i()->in( 'type_id', $ids ) . " )";
|
||||
$clause[] = "( reaction_enabled=? AND app=? AND type=? AND " . \IPS\Db::i()->in( 'type_id', $ids ) . " )";
|
||||
$binds[] = 1;
|
||||
$binds[] = $class::$application;
|
||||
$binds[] = $class::$reputationType;
|
||||
$binds[] = $class::reactionType();
|
||||
}
|
||||
|
||||
$where = array( array_merge( array( implode( ' OR ', $clause ) ), $binds ) );
|
||||
switch( \IPS\Settings::i()->reputation_point_types )
|
||||
foreach ( \IPS\Db::i()->select( array( 'app', 'type', 'type_id', 'member_id', 'rep_rating', 'reaction' ), 'core_reputation_index', $where )->join( 'core_reactions', 'reaction=reaction_id' ) as $rep )
|
||||
{
|
||||
case 'positive':
|
||||
case 'like':
|
||||
$where[] = array( 'rep_rating=?', "1" );
|
||||
break;
|
||||
case 'negative':
|
||||
$where[] = array( 'rep_rating=?', "-1" );
|
||||
break;
|
||||
}
|
||||
|
||||
foreach ( \IPS\Db::i()->select( array( 'app', 'type', 'type_id', 'member_id', 'rep_rating' ), 'core_reputation_index', $where ) as $rep )
|
||||
{
|
||||
$this->reputationData[ $rep['app'] ][ $rep['type'] ][ $rep['type_id'] ][ $rep['member_id'] ] = $rep['rep_rating'];
|
||||
$this->reputationData[ $rep['app'] ][ $rep['type'] ][ $rep['type_id'] ][ $rep['member_id'] ] = $rep['reaction'];
|
||||
|
||||
if ( !isset( $this->reactions[ $rep['app'] ][ $rep['type'] ][ $rep['type_id' ] ][ $rep['reaction'] ] ) )
|
||||
{
|
||||
$this->reactions[ $rep['app'] ][ $rep['type'] ][ $rep['type_id' ] ][ $rep['reaction'] ] = 0;
|
||||
}
|
||||
|
||||
$this->reactions[ $rep['app'] ][ $rep['type'] ][ $rep['type_id' ] ][ $rep['reaction'] ]++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,9 +264,15 @@ class _Results extends \ArrayIterator
|
||||
$containerClass = isset( $itemClass::$containerNodeClass ) ? $itemClass::$containerNodeClass : NULL;
|
||||
|
||||
$reputationData = array();
|
||||
if ( in_array( 'IPS\Content\Reputation', class_implements( $class ) ) and isset( $this->reputationData[ $class::$application ][ $class::$reputationType ][ $data['index_object_id'] ] ) )
|
||||
if ( \IPS\IPS::classUsesTrait( $class, 'IPS\Content\Reactable' ) and isset( $this->reputationData[ $class::$application ][ $class::reactionType() ][ $data['index_object_id'] ] ) )
|
||||
{
|
||||
$reputationData = $this->reputationData[ $class::$application ][ $class::$reputationType ][ $data['index_object_id'] ];
|
||||
$reputationData = $this->reputationData[ $class::$application ][ $class::reactionType() ][ $data['index_object_id'] ];
|
||||
}
|
||||
|
||||
$reactions = array();
|
||||
if ( \IPS\IPS::classUsesTrait( $class, 'IPS\Content\Reactable' ) and isset( $this->reactions[ $class::$application ][ $class::reactionType() ][ $data['index_object_id'] ] ) )
|
||||
{
|
||||
$reactions = $this->reactions[ $class::$application ][ $class::reactionType() ][ $data['index_object_id'] ];
|
||||
}
|
||||
|
||||
/* Ensure we have an item if results are gathered from the map table */
|
||||
@@ -295,14 +307,25 @@ class _Results extends \ArrayIterator
|
||||
$data['index_prefix'] = $this->prefixes[ $data['index_item_index_id'] ]['index_prefix'];
|
||||
}
|
||||
|
||||
$containerData = NULL;
|
||||
if ( $containerClass and isset( $this->containerData[ $containerClass ] ) and isset( $this->containerData[ $containerClass ][ $data['index_container_id'] ] ) )
|
||||
{
|
||||
$containerData = $this->containerData[ $containerClass ][ $data['index_container_id'] ];
|
||||
if ( $data['index_club_id'] and isset( $this->containerData[ 'IPS\Member\Club' ][ $data['index_club_id'] ] ) )
|
||||
{
|
||||
$containerData['_club'] = $this->containerData[ 'IPS\Member\Club' ][ $data['index_club_id'] ];
|
||||
}
|
||||
}
|
||||
|
||||
return new Result\Content(
|
||||
$data,
|
||||
isset( $this->authorData[ $data['index_author'] ] ) ? $this->authorData[ $data['index_author'] ] : array( 'member_id' => 0, 'name' => \IPS\Member::loggedIn()->language()->addToStack('guest'), 'members_seo_name' => '', 'pp_main_photo' => NULL, 'pp_photo_type' => 'none' ),
|
||||
$itemData,
|
||||
( $containerClass and isset( $this->containerData[ $containerClass ] ) and isset( $this->containerData[ $containerClass ][ $data['index_container_id'] ] ) ) ? $this->containerData[ $containerClass ][ $data['index_container_id'] ] : NULL,
|
||||
$containerData,
|
||||
$reputationData,
|
||||
isset( $this->reviewRatings[ $data['index_class'] ][ $data['index_object_id'] ] ) ? $this->reviewRatings[ $data['index_class'] ][ $data['index_object_id'] ] : NULL,
|
||||
in_array( $data['index_item_index_id'], $this->iPostedIn )
|
||||
in_array( $data['index_item_index_id'], $this->iPostedIn ),
|
||||
$reactions
|
||||
);
|
||||
}
|
||||
|
||||
@@ -383,8 +406,15 @@ class _Results extends \ArrayIterator
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ( $results as $result )
|
||||
foreach ( $results as $key => $result )
|
||||
{
|
||||
/* If an item has been removed incorrectly an orphan search index entry can be left. This is already logged in current() so let's not fail catastrophically */
|
||||
if( !$result )
|
||||
{
|
||||
unset( $results[ $key ] );
|
||||
continue;
|
||||
}
|
||||
|
||||
$lastTime = $result->createdDate->getTimestamp();
|
||||
}
|
||||
}
|
||||
@@ -481,6 +511,9 @@ class _Results extends \ArrayIterator
|
||||
/* If an application was not updated or is not installed, do not try to fetch it or we can get a class does not exist fatal error */
|
||||
$where[] = array( "follow_app IN('" . implode( "','", array_keys( \IPS\Application::enabledApplications() ) ) . "')" );
|
||||
|
||||
$lastClass = NULL;
|
||||
$lastMember = NULL;
|
||||
|
||||
foreach ( \IPS\Db::i()->select( array( 'follow_app', 'follow_area', 'follow_rel_id', 'follow_member_id', 'follow_added' ), 'core_follow', $where, 'follow_added DESC', 10 ) as $follow )
|
||||
{
|
||||
if ( $follow['follow_app'] == 'core' and $follow['follow_area'] == 'member' )
|
||||
@@ -493,66 +526,121 @@ class _Results extends \ArrayIterator
|
||||
else
|
||||
{
|
||||
$class = 'IPS\\' . $follow['follow_app'] . '\\' . ucfirst( $follow['follow_area'] );
|
||||
|
||||
try
|
||||
{
|
||||
if ( class_exists( $class ) )
|
||||
{
|
||||
$thingBeingFollowed = $class::loadAndCheckPerms( $follow['follow_rel_id'] );
|
||||
$thingBeingFollowed = $class::loadAndCheckPerms( $follow['follow_rel_id'] );
|
||||
$urlToThing = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $thingBeingFollowed->url(), FALSE, $thingBeingFollowed instanceof \IPS\Node\Model ? $thingBeingFollowed->_title : $thingBeingFollowed->mapped('title'), FALSE );
|
||||
|
||||
/* Do we need to merge with the last result? */
|
||||
if( $lastClass !== NULL AND $lastClass === $class AND $lastMember === $follow['follow_member_id'] AND count( $extraItems ) )
|
||||
{
|
||||
$extraItem = array_pop( $extraItems );
|
||||
|
||||
$extraItems[] = new Result\Custom(
|
||||
\IPS\DateTime::ts( $follow['follow_added'] ),
|
||||
\IPS\Member::loggedIn()->language()->addToStack( 'activity_member_followed', FALSE, array( 'htmlsprintf' => array( \IPS\Theme::i()->getTemplate( 'global', 'core', 'front' )->userLink( \IPS\Member::load( $follow['follow_member_id'] ) ), \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $thingBeingFollowed->url(), FALSE, $thingBeingFollowed instanceof \IPS\Node\Model ? $thingBeingFollowed->_title : $thingBeingFollowed->mapped('title'), FALSE ) ) ) )
|
||||
);
|
||||
$mergeList = array_merge( array( $urlToThing ), $extraItem->getMergeData() );
|
||||
$listToDisplay = $mergeList;
|
||||
|
||||
if( count( $mergeList ) > 3 )
|
||||
{
|
||||
$listToDisplay = array_slice( $mergeList, 0, 3 );
|
||||
$listToDisplay[] = \IPS\Member::loggedIn()->language()->addToStack( 'and_x_others', FALSE, array( 'pluralize' => array( count( $mergeList ) - 3 ) ) );
|
||||
}
|
||||
$extraItem->mergeInData( \IPS\Member::loggedIn()->language()->addToStack( 'activity_member_followed', FALSE, array( 'htmlsprintf' => array( \IPS\Theme::i()->getTemplate( 'global', 'core', 'front' )->userLink( \IPS\Member::load( $follow['follow_member_id'] ) ), \IPS\Member::loggedIn()->language()->formatList( $listToDisplay ) ) ) ), $urlToThing );
|
||||
$extraItems[] = $extraItem;
|
||||
}
|
||||
else
|
||||
{
|
||||
$extraItems[] = new Result\Custom(
|
||||
\IPS\DateTime::ts( $follow['follow_added'] ),
|
||||
\IPS\Member::loggedIn()->language()->addToStack( 'activity_member_followed', FALSE, array( 'htmlsprintf' => array( \IPS\Theme::i()->getTemplate( 'global', 'core', 'front' )->userLink( \IPS\Member::load( $follow['follow_member_id'] ) ), $urlToThing ) ) ),
|
||||
NULL,
|
||||
$urlToThing
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
|
||||
$lastClass = $class;
|
||||
$lastMember = $follow['follow_member_id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Likes */
|
||||
if ( \IPS\Settings::i()->reputation_enabled and \IPS\Member::loggedIn()->group['gbw_view_reps'] and ( in_array( 'like', $extra ) or in_array( 'rep_neg', $extra ) ) )
|
||||
if ( \IPS\Settings::i()->reputation_enabled and \IPS\Member::loggedIn()->group['gbw_view_reps'] and ( in_array( 'like', $extra ) or in_array( 'react', $extra ) ) )
|
||||
{
|
||||
$where = array( array( 'rep_date>?', $lastTime ) );
|
||||
$where[] = array( 'reaction_enabled=?', 1 );
|
||||
if ( $firstTime )
|
||||
{
|
||||
$where[] = array( 'rep_date<?', $firstTime );
|
||||
}
|
||||
if ( !in_array( 'rep_neg', $extra ) or ( \IPS\Settings::i()->reputation_point_types != 'both' and \IPS\Settings::i()->reputation_point_types != 'negative' ) )
|
||||
{
|
||||
$where[] = array( 'rep_rating=1' );
|
||||
}
|
||||
elseif ( !in_array( 'like', $extra ) or ( \IPS\Settings::i()->reputation_point_types == 'negative' ) )
|
||||
{
|
||||
$where[] = array( 'rep_rating=-1' );
|
||||
}
|
||||
|
||||
/* get only the reputation data for installed applications */
|
||||
$where[] = \IPS\Db::i()->in( 'app', array_keys( \IPS\Application::applications() ) ) ;
|
||||
|
||||
if ( $author )
|
||||
{
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_reputation_index', array_merge( $where, array( array( 'member_id=?', $author->member_id ) ) ), 'rep_date DESC', 10 ) as $rep )
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_reputation_index', array_merge( $where, array( array( 'member_id=?', $author->member_id ) ) ), 'rep_date DESC', 10 )->join( 'core_reactions', 'reaction=reaction_id' ) as $rep )
|
||||
{
|
||||
$this->addReputationExtraItem( $rep, $extraItems );
|
||||
}
|
||||
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_reputation_index', array_merge( $where, array( array( 'member_received=?', $author->member_id ) ) ), 'rep_date DESC', 10 ) as $rep )
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_reputation_index', array_merge( $where, array( array( 'member_received=?', $author->member_id ) ) ), 'rep_date DESC', 10 )->join( 'core_reactions', 'reaction=reaction_id' ) as $rep )
|
||||
{
|
||||
$this->addReputationExtraItem( $rep, $extraItems );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_reputation_index', $where, 'rep_date DESC', 10 ) as $rep )
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_reputation_index', $where, 'rep_date DESC', 10 )->join( 'core_reactions', 'reaction=reaction_id' ) as $rep )
|
||||
{
|
||||
$this->addReputationExtraItem( $rep, $extraItems );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Clubs */
|
||||
if ( \IPS\Settings::i()->clubs and in_array( 'clubs', $extra ) )
|
||||
{
|
||||
$where = array( array( 'created>?', $lastTime ) );
|
||||
if ( $firstTime )
|
||||
{
|
||||
$where[] = array( 'created<?', $firstTime );
|
||||
}
|
||||
if ( $author )
|
||||
{
|
||||
$where[] = array( 'owner=?', $author->member_id );
|
||||
}
|
||||
|
||||
foreach ( \IPS\Member\Club::clubs( \IPS\Member::loggedIn(), NULL, 'created', FALSE, array(), $where ) as $club )
|
||||
{
|
||||
if ( $club->owner AND $club->owner->member_id )
|
||||
{
|
||||
$extraItems[] = new Result\Custom(
|
||||
$club->created,
|
||||
\IPS\Member::loggedIn()->language()->addToStack( 'activity_club', FALSE, array( 'htmlsprintf' => array( \IPS\Theme::i()->getTemplate( 'global', 'core', 'front' )->userLink( $club->owner ), \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $club->url(), FALSE, $club->name, FALSE ) ) ) )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Extensions */
|
||||
foreach ( \IPS\Application::allExtensions( 'core', 'StreamItems', TRUE, 'core' ) as $key => $extension )
|
||||
{
|
||||
$settingKey = "all_activity_" . mb_strtolower( $key );
|
||||
|
||||
if( method_exists( $extension, 'extraItems' ) and \IPS\Settings::i()->$settingKey )
|
||||
{
|
||||
$extraItems = array_merge( $extraItems, $extension->extraItems( $author, $lastTime, $firstTime ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Merge them in */
|
||||
if ( !empty( $extraItems ) )
|
||||
{
|
||||
@@ -594,7 +682,7 @@ class _Results extends \ArrayIterator
|
||||
{
|
||||
foreach ( $ext->classes as $class )
|
||||
{
|
||||
if ( in_array( 'IPS\Content\Reputation', class_implements( $class ) ) and $class::$reputationType == $rep['type'] )
|
||||
if ( \IPS\IPS::classUsesTrait( $class, 'IPS\Content\Reactable' ) and $class::reactionType() == $rep['type'] )
|
||||
{
|
||||
$thingBeingRepped = $class::loadAndCheckPerms( $rep['type_id'] );
|
||||
break;
|
||||
@@ -602,7 +690,7 @@ class _Results extends \ArrayIterator
|
||||
if ( isset( $class::$commentClass ) )
|
||||
{
|
||||
$commentClass = $class::$commentClass;
|
||||
if ( in_array( 'IPS\Content\Reputation', class_implements( $commentClass ) ) and $commentClass::$reputationType == $rep['type'] )
|
||||
if ( \IPS\IPS::classUsesTrait( $commentClass, 'IPS\Content\Reactable' ) and $commentClass::reactionType() == $rep['type'] )
|
||||
{
|
||||
$thingBeingRepped = $commentClass::loadAndCheckPerms( $rep['type_id'] );
|
||||
break;
|
||||
@@ -611,7 +699,7 @@ class _Results extends \ArrayIterator
|
||||
if ( isset( $class::$reviewClass ) )
|
||||
{
|
||||
$reviewClass = $class::$reviewClass;
|
||||
if ( in_array( 'IPS\Content\Reputation', class_implements( $reviewClass ) ) and $reviewClass::$reputationType == $rep['type'] )
|
||||
if ( \IPS\IPS::classUsesTrait( $reviewClass, 'IPS\Content\Reactable' ) and $reviewClass::reactionType() == $rep['type'] )
|
||||
{
|
||||
$thingBeingRepped = $reviewClass::loadAndCheckPerms( $rep['type_id'] );
|
||||
break;
|
||||
@@ -624,27 +712,31 @@ class _Results extends \ArrayIterator
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
|
||||
if ( \IPS\Settings::i()->reputation_point_types == 'like' )
|
||||
if ( \IPS\Content\Reaction::isLikeMode() )
|
||||
{
|
||||
$lang = 'activity_member_liked';
|
||||
}
|
||||
elseif ( $rep['rep_rating'] > 0 )
|
||||
{
|
||||
$lang = 'activity_rep_pos';
|
||||
$extraItems[] = new Result\Custom(
|
||||
\IPS\DateTime::ts( $rep['rep_date'] ),
|
||||
\IPS\Member::loggedIn()->language()->addToStack( 'activity_member_liked', FALSE, array( 'htmlsprintf' => array(
|
||||
\IPS\Theme::i()->getTemplate( 'global', 'core', 'front' )->userLink( \IPS\Member::load( $rep['member_id'] ) ),
|
||||
$thingBeingRepped->indefiniteArticle(),
|
||||
\IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $thingBeingRepped->url(), FALSE, $thingBeingRepped instanceof \IPS\Content\Item ? $thingBeingRepped->mapped('title') : $thingBeingRepped->item()->mapped('title'), FALSE )
|
||||
) ) )
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$lang = 'activity_rep_neg';
|
||||
$reaction = \IPS\Content\Reaction::load( $rep['reaction'] );
|
||||
$extraItems[] = new Result\Custom(
|
||||
\IPS\DateTime::ts( $rep['rep_date'] ),
|
||||
\IPS\Member::loggedIn()->language()->addToStack( 'activity_member_reacted', FALSE, array( 'htmlsprintf' => array(
|
||||
(string) $reaction->_icon,
|
||||
$reaction->_title,
|
||||
\IPS\Theme::i()->getTemplate( 'global', 'core', 'front' )->userLink( \IPS\Member::load( $rep['member_id'] ) ),
|
||||
$thingBeingRepped->indefiniteArticle(),
|
||||
\IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $thingBeingRepped->url(), FALSE, $thingBeingRepped instanceof \IPS\Content\Item ? $thingBeingRepped->mapped('title') : $thingBeingRepped->item()->mapped('title'), FALSE )
|
||||
) ) )
|
||||
);
|
||||
}
|
||||
|
||||
$extraItems[] = new Result\Custom(
|
||||
\IPS\DateTime::ts( $rep['rep_date'] ),
|
||||
\IPS\Member::loggedIn()->language()->addToStack( $lang, FALSE, array( 'htmlsprintf' => array(
|
||||
\IPS\Theme::i()->getTemplate( 'global', 'core', 'front' )->userLink( \IPS\Member::load( $rep['member_id'] ) ),
|
||||
$thingBeingRepped->indefiniteArticle(),
|
||||
\IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $thingBeingRepped->url(), FALSE, $thingBeingRepped instanceof \IPS\Content\Item ? $thingBeingRepped->mapped('title') : $thingBeingRepped->item()->mapped('title'), FALSE )
|
||||
) ) )
|
||||
);
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user