Version 4.1.2
This commit is contained in:
1 parent
3ba79295ee
commit
28bd025b35
1131 files changed
+63658
-20579
No files matched your search
@@ -96,15 +96,16 @@ class _Advertisement extends \IPS\Patterns\ActiveRecord
|
||||
}
|
||||
}
|
||||
|
||||
/* Weed out any we don't see due to our group. This is done after loading the advertisements so that the cache can be properly primed regardless of group. */
|
||||
/* Weed out any we don't see due to our group. This is done after loading the advertisements so that the cache can be properly primed regardless of group. Note that $ad->exempt, is, confusingly who to SHOW to, not who is exempt */
|
||||
foreach( static::$advertisements as $adLocation => $ads )
|
||||
{
|
||||
foreach( $ads as $index => $ad )
|
||||
{
|
||||
if ( $ad->exempt != '*' )
|
||||
{
|
||||
|
||||
$groupsToHideFrom = array_diff( array_keys(\IPS\Member\Group::groups()), json_decode( $ad->exempt, TRUE ) );
|
||||
|
||||
|
||||
if ( \IPS\Member::loggedIn()->inGroup( $groupsToHideFrom ) )
|
||||
{
|
||||
unset( static::$advertisements[ $adLocation ][ $index ] );
|
||||
|
||||
@@ -53,15 +53,14 @@ class _Table extends \IPS\Helpers\Table\Db
|
||||
|
||||
if( is_subclass_of( $className, 'IPS\Content\Item' ) )
|
||||
{
|
||||
$this->rowsTemplate = $className::contentTableTemplate();
|
||||
$this->rowsTemplate = $className::manageFollowRows();
|
||||
$containerClass = $className::$containerNodeClass;
|
||||
$this->group = 'follow_id';
|
||||
|
||||
$this->joins = array(
|
||||
array( 'from' => 'core_permission_index', 'where' => array( "core_permission_index.app=? AND core_permission_index.perm_type=?", $containerClass::$permApp, $containerClass::$permType ) ),
|
||||
$this->joins = array(
|
||||
array( 'from' => $className::$databaseTable, 'where' => array( $className::$databaseTable . '.' . $className::$databasePrefix . $className::$databaseColumnId . '=core_follow.follow_rel_id AND core_follow.follow_app=?', $currentType[0] ) )
|
||||
);
|
||||
|
||||
|
||||
/* Exclude hidden items */
|
||||
if ( in_array( 'IPS\Content\Hideable', class_implements( $className ) ) and !$className::canViewHiddenItems() )
|
||||
{
|
||||
@@ -78,6 +77,17 @@ class _Table extends \IPS\Helpers\Table\Db
|
||||
}
|
||||
}
|
||||
|
||||
/* Additional where */
|
||||
$joinContainer = $className::$containerNodeClass ? TRUE : FALSE;
|
||||
$joins = array();
|
||||
$extraWhere = $className::followWhere( $joinContainer, $joins );
|
||||
|
||||
if ( $joinContainer )
|
||||
{
|
||||
$containerClass = $className::$containerNodeClass;
|
||||
$this->joins[] = array( 'from' => $containerClass::$databaseTable, 'where' => $containerClass::$databaseTable . '.' . $containerClass::$databasePrefix . $containerClass::$databaseColumnId . '=' . $className::$databaseTable . '.' . $className::$databasePrefix . $className::$databaseColumnMap['container'], 'type' => 'STRAIGHT_JOIN' );
|
||||
}
|
||||
|
||||
/* Permissions */
|
||||
if ( in_array( 'IPS\Content\Permissions', class_implements( $className ) ) )
|
||||
{
|
||||
@@ -85,10 +95,9 @@ class _Table extends \IPS\Helpers\Table\Db
|
||||
$this->where[0] .= ' AND (' . \IPS\Db::i()->findInSet( 'core_permission_index.perm_' . $containerClass::$permissionMap['view'], \IPS\Member::loggedIn()->groups ) . ' OR core_permission_index.perm_' . $containerClass::$permissionMap['view'] . "='*' )";
|
||||
}
|
||||
|
||||
/* Additional where */
|
||||
$joinContainer = FALSE;
|
||||
$joins = array();
|
||||
if ( $extraWhere = $className::followWhere( $joinContainer, $joins ) )
|
||||
$this->joins[] = array( 'from' => 'core_permission_index', 'where' => array( "core_permission_index.app=? AND core_permission_index.perm_type=? AND core_permission_index.perm_type_id=" . $containerClass::$databaseTable . '.' . $containerClass::$databasePrefix . $containerClass::$databaseColumnId, $containerClass::$permApp, $containerClass::$permType ) );
|
||||
|
||||
if ( $extraWhere )
|
||||
{
|
||||
if( isset( $extraWhere['item'] ) )
|
||||
{
|
||||
@@ -104,11 +113,7 @@ class _Table extends \IPS\Helpers\Table\Db
|
||||
$this->where = array_merge( array( $this->where ), $extraWhere );
|
||||
}
|
||||
}
|
||||
if ( $joinContainer )
|
||||
{
|
||||
$containerClass = $className::$containerNodeClass;
|
||||
$this->joins[] = array( 'from' => $containerClass::$databaseTable, 'where' => $containerClass::$databaseTable . '.' . $containerClass::$databasePrefix . $containerClass::$databaseColumnId . '=' . $className::$databaseTable . '.' . $className::$databasePrefix . $className::$databaseColumnMap['container'] );
|
||||
}
|
||||
|
||||
$this->joins = array_merge( $this->joins, $joins );
|
||||
}
|
||||
elseif( $className == "\IPS\Member" )
|
||||
@@ -117,17 +122,17 @@ class _Table extends \IPS\Helpers\Table\Db
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->rowsTemplate = $className::nodeTableTemplate();
|
||||
$this->rowsTemplate = $className::manageFollowNodeRow();
|
||||
|
||||
$this->joins = array(
|
||||
array( 'from' => 'core_permission_index', 'where' => array( "core_permission_index.app=? AND core_permission_index.perm_type=? AND core_permission_index.perm_type_id=?", $className::$permApp, $className::$permType, $className::$databaseTable . '.' . $className::$databasePrefix . $className::$databaseColumnId ) ),
|
||||
array( 'from' => $className::$databaseTable, 'where' => array( $className::$databaseTable . '.' . $className::$databasePrefix . $className::$databaseColumnId . '=follow_rel_id AND follow_app=?', $currentType[0] ) ),
|
||||
array( 'from' => 'core_permission_index', 'where' => array( "core_permission_index.app=? AND core_permission_index.perm_type=? AND core_permission_index.perm_type_id=" . $className::$databaseTable . '.' . $className::$databasePrefix . $className::$databaseColumnId, $className::$permApp, $className::$permType ) ),
|
||||
);
|
||||
|
||||
/* Permission check? */
|
||||
if ( in_array( 'IPS\Node\Permissions', class_implements( $className ) ) )
|
||||
{
|
||||
$this->where[1] .= ' AND (' . \IPS\Db::i()->findInSet( 'core_permission_index.perm_' . $className::$permissionMap['view'], \IPS\Member::loggedIn()->groups ) . ' OR ' . 'core_permission_index.perm_' . $className::$permissionMap['view'] . "='*' )";
|
||||
$this->where[0] .= ' AND (' . \IPS\Db::i()->findInSet( 'core_permission_index.perm_' . $className::$permissionMap['view'], \IPS\Member::loggedIn()->groups ) . ' OR ' . 'core_permission_index.perm_' . $className::$permissionMap['view'] . "='*' )";
|
||||
}
|
||||
|
||||
/* Additional where */
|
||||
|
||||
@@ -0,0 +1,408 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Front Navigation Handler
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Core
|
||||
* @since 30 Jun 2015
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\core;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Front Navigation Extension: Custom Item
|
||||
*/
|
||||
class _FrontNavigation
|
||||
{
|
||||
/**
|
||||
* @brief Singleton Instances
|
||||
* @note This needs to be declared in any child classes as well, only declaring here for editor code-complete/error-check functionality
|
||||
*/
|
||||
protected static $instance = NULL;
|
||||
|
||||
/**
|
||||
* Get instance
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public static function i()
|
||||
{
|
||||
if( static::$instance === NULL )
|
||||
{
|
||||
$classname = get_called_class();
|
||||
static::$instance = new $classname;
|
||||
}
|
||||
|
||||
return static::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data store
|
||||
*
|
||||
* @param bool $noStore If true, will skip datastore and get from DB (used for ACP preview)
|
||||
* @return array
|
||||
*/
|
||||
public static function frontNavigation( $noStore=FALSE )
|
||||
{
|
||||
if ( $noStore or !isset( \IPS\Data\Store::i()->frontNavigation ) )
|
||||
{
|
||||
$frontNavigation = array( 0 => array(), 1 => array() );
|
||||
$select = \IPS\Db::i()->select( '*', 'core_menu', NULL, 'position' );
|
||||
if ( count( $select ) )
|
||||
{
|
||||
foreach ( $select as $item )
|
||||
{
|
||||
if ( \IPS\Application::appIsEnabled( $item['app'] ) )
|
||||
{
|
||||
$frontNavigation[ intval( $item['parent'] ) ][ $item['id'] ] = $item;
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif ( !$noStore )
|
||||
{
|
||||
static::buildDefaultFrontNavigation();
|
||||
return static::frontNavigation();
|
||||
}
|
||||
if ( $noStore )
|
||||
{
|
||||
return $frontNavigation;
|
||||
}
|
||||
\IPS\Data\Store::i()->frontNavigation = $frontNavigation;
|
||||
}
|
||||
return \IPS\Data\Store::i()->frontNavigation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete front navigation items by application
|
||||
*
|
||||
* @param \IPS\Application $app Application deleted
|
||||
* @return void
|
||||
*/
|
||||
public static function deleteByApplication( \IPS\Application $app )
|
||||
{
|
||||
foreach( \IPS\Db::i()->select( '*', 'core_menu', array( array( 'extension=?', 'CustomItem' ) ) ) as $row )
|
||||
{
|
||||
$config = json_decode( $row['config'], TRUE );
|
||||
|
||||
if ( isset( $config['menu_custom_item_url'] ) and $config['menu_custom_item_url'] and isset( $config['internal'] ) and $config['internal'] )
|
||||
{
|
||||
try
|
||||
{
|
||||
$data = \IPS\Http\Url::internal( $config['menu_custom_item_url'], NULL, $config['internal'] )->getFriendlyUrlData();
|
||||
|
||||
if ( ! empty( $data['app'] ) and $data['app'] === $app->directory )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_menu', array( 'id=?', $row['id'] ) );
|
||||
}
|
||||
}
|
||||
catch( \Exception $e ) { }
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Db::i()->delete( 'core_menu', array( 'app=?', $app->directory ) );
|
||||
|
||||
unset( \IPS\Data\Store::i()->frontNavigation );
|
||||
}
|
||||
|
||||
/**
|
||||
* Build default front navigation
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function buildDefaultFrontNavigation()
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_menu' );
|
||||
|
||||
$topLevelPosition = 1;
|
||||
|
||||
/* Browse */
|
||||
\IPS\Db::i()->insert( 'core_menu', array(
|
||||
'id' => 1,
|
||||
'app' => 'core',
|
||||
'extension' => 'CustomItem',
|
||||
'config' => json_encode( array( 'menu_custom_item_url' => '', 'internal' => '' ) ),
|
||||
'position' => $topLevelPosition++,
|
||||
'parent' => NULL,
|
||||
'permissions' => '*',
|
||||
) );
|
||||
|
||||
/* Activity */
|
||||
\IPS\Db::i()->insert( 'core_menu', array(
|
||||
'id' => 2,
|
||||
'app' => 'core',
|
||||
'extension' => 'CustomItem',
|
||||
'config' => json_encode( array( 'menu_custom_item_url' => 'app=core&module=discover&controller=streams', 'internal' => 'discover_all' ) ),
|
||||
'position' => $topLevelPosition++,
|
||||
'parent' => NULL,
|
||||
'permissions' => '*',
|
||||
) );
|
||||
|
||||
/* Commerce requires a bit of a special set up */
|
||||
if ( \IPS\Application::appIsEnabled('nexus') )
|
||||
{
|
||||
/* Store */
|
||||
\IPS\Db::i()->insert( 'core_menu', array(
|
||||
'id' => 4,
|
||||
'app' => 'nexus',
|
||||
'extension' => 'Store',
|
||||
'config' => json_encode( array() ),
|
||||
'position' => $topLevelPosition++,
|
||||
'parent' => NULL,
|
||||
'permissions' => '*',
|
||||
) );
|
||||
|
||||
/* Support */
|
||||
\IPS\Db::i()->insert( 'core_menu', array(
|
||||
'id' => 5,
|
||||
'app' => 'core',
|
||||
'extension' => 'CustomItem',
|
||||
'config' => json_encode( array( 'menu_custom_item_url' => 'app=nexus&module=support&controller=home', 'internal' => 'support' ) ),
|
||||
'position' => $topLevelPosition++,
|
||||
'parent' => NULL,
|
||||
'permissions' => '*',
|
||||
) );
|
||||
|
||||
/* My Details */
|
||||
\IPS\Db::i()->insert( 'core_menu', array(
|
||||
'id' => 6,
|
||||
'app' => 'core',
|
||||
'extension' => 'Menu',
|
||||
'config' => json_encode( array() ),
|
||||
'position' => 5,
|
||||
'parent' => 4,
|
||||
'permissions' => '*',
|
||||
) );
|
||||
}
|
||||
|
||||
/* Browse subitems */
|
||||
$communityApps = array( 'forums', 'gallery', 'downloads', 'cms', 'blog', 'calendar', 'chat' );
|
||||
$browsePosition = 1;
|
||||
$toInsert = array();
|
||||
foreach ( $communityApps as $app )
|
||||
{
|
||||
if ( \IPS\Application::appIsEnabled( $app ) )
|
||||
{
|
||||
foreach ( array_keys( \IPS\Application::load( $app )->extensions( 'core', 'FrontNavigation', FALSE ) ) as $key )
|
||||
{
|
||||
$config = array();
|
||||
if ( $app === 'cms' and $key === 'Cms' )
|
||||
{
|
||||
/* Cms.php was added to prevent upgrades breaking */
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( $app === 'cms' and $key === 'Pages' )
|
||||
{
|
||||
try
|
||||
{
|
||||
$defaultPage = \IPS\cms\Pages\Page::getDefaultPage();
|
||||
$config = array( 'menu_content_page' => $defaultPage->id, 'menu_title_page_type' => 0 );
|
||||
}
|
||||
catch( \OutOfRangeException $ex )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$toInsert[] = array(
|
||||
'app' => $app,
|
||||
'extension' => $key,
|
||||
'config' => json_encode( $config ),
|
||||
'position' => $browsePosition++,
|
||||
'parent' => 1,
|
||||
'permissions' => '',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Insert Apps */
|
||||
\IPS\Db::i()->insert( 'core_menu', $toInsert );
|
||||
|
||||
/* Other 'browse' items */
|
||||
foreach ( array( 'Guidelines', 'StaffDirectory', 'OnlineUsers' ) as $k )
|
||||
{
|
||||
\IPS\Db::i()->insert( 'core_menu', array(
|
||||
'app' => 'core',
|
||||
'extension' => $k,
|
||||
'config' => json_encode( array() ),
|
||||
'position' => $browsePosition++,
|
||||
'parent' => 1,
|
||||
'permissions' => '',
|
||||
) );
|
||||
}
|
||||
|
||||
/* Activity Subitems */
|
||||
$activityPosition = 1;
|
||||
foreach ( array( 'AllActivity', 'YourActivityStreams' ) as $k )
|
||||
{
|
||||
\IPS\Db::i()->insert( 'core_menu', array(
|
||||
'app' => 'core',
|
||||
'extension' => $k,
|
||||
'config' => json_encode( array() ),
|
||||
'position' => $activityPosition++,
|
||||
'parent' => 2,
|
||||
'permissions' => '',
|
||||
) );
|
||||
}
|
||||
foreach ( array( 1, 2 ) as $k )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\core\Stream::load( $k );
|
||||
\IPS\Db::i()->insert( 'core_menu', array(
|
||||
'app' => 'core',
|
||||
'extension' => 'YourActivityStreamsItem',
|
||||
'config' => json_encode( array( 'menu_stream_id' => $k ) ),
|
||||
'position' => $activityPosition++,
|
||||
'parent' => 2,
|
||||
'permissions' => '',
|
||||
) );
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
}
|
||||
foreach ( array( 'Search' ) as $k )
|
||||
{
|
||||
\IPS\Db::i()->insert( 'core_menu', array(
|
||||
'app' => 'core',
|
||||
'extension' => $k,
|
||||
'config' => json_encode( array() ),
|
||||
'position' => $activityPosition++,
|
||||
'parent' => 2,
|
||||
'permissions' => '',
|
||||
) );
|
||||
}
|
||||
|
||||
/* Commerce requires a bit of a special set up */
|
||||
if ( \IPS\Application::appIsEnabled('nexus') )
|
||||
{
|
||||
$storePosition = 1;
|
||||
foreach ( array( 'Donations', 'Orders', 'Purchases' ) as $k )
|
||||
{
|
||||
\IPS\Db::i()->insert( 'core_menu', array(
|
||||
'app' => 'nexus',
|
||||
'extension' => $k,
|
||||
'config' => json_encode( array() ),
|
||||
'position' => $storePosition++,
|
||||
'parent' => 4,
|
||||
'permissions' => '',
|
||||
) );
|
||||
}
|
||||
|
||||
$myDetailsPosition = 1;
|
||||
foreach ( array( 'Info', 'Addresses', 'Cards', 'Credit', 'Alternatives', 'Referrals' ) as $k )
|
||||
{
|
||||
\IPS\Db::i()->insert( 'core_menu', array(
|
||||
'app' => 'nexus',
|
||||
'extension' => $k,
|
||||
'config' => json_encode( array() ),
|
||||
'position' => $myDetailsPosition++,
|
||||
'parent' => 6,
|
||||
'permissions' => '',
|
||||
) );
|
||||
}
|
||||
|
||||
$supportPosition = 1;
|
||||
foreach ( array( 'Support', 'NetworkStatus' ) as $k )
|
||||
{
|
||||
\IPS\Db::i()->insert( 'core_menu', array(
|
||||
'app' => 'nexus',
|
||||
'extension' => $k,
|
||||
'config' => json_encode( array() ),
|
||||
'position' => $supportPosition++,
|
||||
'parent' => 5,
|
||||
'permissions' => '',
|
||||
) );
|
||||
}
|
||||
}
|
||||
|
||||
/* Other apps */
|
||||
$toGiveToParents = array();
|
||||
$parentIds = array();
|
||||
foreach ( \IPS\Application::allExtensions( 'core', 'FrontNavigation', FALSE, NULL, NULL, FALSE ) as $key => $class )
|
||||
{
|
||||
$exploded = explode( '_', $key );
|
||||
if ( !in_array( $exploded[0], array_merge( $communityApps, array( 'core', 'nexus' ) ) ) )
|
||||
{
|
||||
$parentIds[ $exploded[0] ][ $exploded[1] ] = \IPS\Db::i()->insert( 'core_menu', array(
|
||||
'app' => $exploded[0],
|
||||
'extension' => $exploded[1],
|
||||
'config' => json_encode( array() ),
|
||||
'position' => $topLevelPosition++,
|
||||
'parent' => NULL,
|
||||
'permissions' => '',
|
||||
) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The active primary navigation bar
|
||||
*/
|
||||
public $activePrimaryNavBar = NULL;
|
||||
|
||||
/**
|
||||
* Get roots
|
||||
*
|
||||
* @param bool $noStore If true, will skip datastore and get from DB (used for ACP preview)
|
||||
* @return array
|
||||
*/
|
||||
public function roots( $noStore=FALSE )
|
||||
{
|
||||
$frontNavigation = static::frontNavigation( $noStore );
|
||||
$return = array();
|
||||
foreach ( $frontNavigation[0] as $item )
|
||||
{
|
||||
$class = 'IPS\\' . $item['app'] . '\extensions\core\FrontNavigation\\' . $item['extension'];
|
||||
$object = new $class( json_decode( $item['config'], TRUE ), $item['id'], $item['permissions'] );
|
||||
if ( !$this->activePrimaryNavBar )
|
||||
{
|
||||
$this->activePrimaryNavBar = $item['id'];
|
||||
}
|
||||
$return[ $item['id'] ] = $object;
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sub-bars
|
||||
*
|
||||
* @param bool $noStore If true, will skip datastore and get from DB (used for ACP preview)
|
||||
* @return array
|
||||
*/
|
||||
public function subBars( $noStore=FALSE )
|
||||
{
|
||||
$frontNavigation = static::frontNavigation( $noStore );
|
||||
$return = array();
|
||||
$parentIDs = array();
|
||||
// Changed so that empty sub bars don't add an array to their parent, allowing us to do count( $subBars ) and figure
|
||||
// out if there's any to show.
|
||||
foreach ( $frontNavigation[0] as $item )
|
||||
{
|
||||
$parentIDs[] = $item['id'];
|
||||
}
|
||||
|
||||
foreach ( $parentIDs as $i )
|
||||
{
|
||||
if ( isset( $frontNavigation[$i] ) )
|
||||
{
|
||||
foreach ( $frontNavigation[$i] as $item )
|
||||
{
|
||||
$class = 'IPS\\' . $item['app'] . '\extensions\core\FrontNavigation\\' . $item['extension'];
|
||||
$return[ $item['parent'] ][ $item['id'] ] = new $class( json_decode( $item['config'], TRUE ), $item['id'], $item['permissions'] );
|
||||
}
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Abstract Front Navigation Extension
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Core
|
||||
* @since 30 Jun 2015
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\core\FrontNavigation;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Front Navigation Extension: Custom Item
|
||||
*/
|
||||
abstract class _FrontNavigationAbstract
|
||||
{
|
||||
const DEFAULT_LOCATION_ROOT = NULL;
|
||||
const DEFAULT_LOCATION_BROWSE = 1;
|
||||
const DEFAULT_LOCATION_ACTIVITY = 2;
|
||||
const DEFAULT_LOCATION_MORE = 3;
|
||||
|
||||
/**
|
||||
* Get sub items of an item
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function subItems()
|
||||
{
|
||||
$frontNavigation = \IPS\core\FrontNavigation::frontNavigation();
|
||||
$return = array();
|
||||
if ( isset( $frontNavigation[ $this->id ] ) )
|
||||
{
|
||||
foreach ( $frontNavigation[ $this->id ] as $item )
|
||||
{
|
||||
$class = 'IPS\\' . $item['app'] . '\extensions\core\FrontNavigation\\' . $item['extension'];
|
||||
$return[ $item['id'] ] = new $class( json_decode( $item['config'], TRUE ), $item['id'], $item['permissions'] );
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default Location
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function defaultLocation()
|
||||
{
|
||||
return static::DEFAULT_LOCATION_BROWSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow multiple instances?
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function allowMultiple()
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get configuration fields
|
||||
*
|
||||
* @param array $configuration The existing configuration, if editing an existing item
|
||||
* @param int $id The ID number of the existing item, if editing
|
||||
* @return array
|
||||
*/
|
||||
public static function configuration( $existingConfiguration, $id = NULL )
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse configuration fields
|
||||
*
|
||||
* @param array $configuration The values received from the form
|
||||
* @return array
|
||||
*/
|
||||
public static function parseConfiguration( $configuration, $id )
|
||||
{
|
||||
return $configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The configuration
|
||||
*/
|
||||
protected $configuration;
|
||||
|
||||
/**
|
||||
* @brief The ID number
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* @brief The permissions
|
||||
*/
|
||||
public $permissions;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $configuration The configuration
|
||||
* @param int $id The ID number
|
||||
* @param string $permissions The permissions (* or comma-delimited list of groups)
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( $configuration, $id, $permissions )
|
||||
{
|
||||
$this->configuration = $configuration;
|
||||
$this->id = $id;
|
||||
$this->permissions = $permissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Permissions can be inherited?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function permissionsCanInherit()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can access?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canView()
|
||||
{
|
||||
if ( $this->permissions and $this->permissions != '*' )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->inGroup( explode( ',', $this->permissions ) );
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Title
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public function title();
|
||||
|
||||
/**
|
||||
* Get Link
|
||||
*
|
||||
* @return \IPS\Http\Url
|
||||
*/
|
||||
abstract public function link();
|
||||
|
||||
/**
|
||||
* Get Attributes
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function attributes()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Active?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function active()
|
||||
{
|
||||
foreach ( $this->subItems() as $item )
|
||||
{
|
||||
if ( $item->active() )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Children
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function children()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -612,4 +612,76 @@ class _Conversation extends \IPS\Content\Item
|
||||
$this->delete();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Particpant blurb
|
||||
*/
|
||||
public $participantBlurb = NULL;
|
||||
|
||||
/**
|
||||
* Get participant blurb
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function participantBlurb()
|
||||
{
|
||||
if( $this->participantBlurb !== NULL )
|
||||
{
|
||||
return $this->participantBlurb;
|
||||
}
|
||||
|
||||
$people = array();
|
||||
foreach( \IPS\Db::i()->select( 'member_id, name', 'core_members', array( \IPS\Db::i()->in( 'member_id', array_keys( $this->maps() ) ) ) ) as $member )
|
||||
{
|
||||
if ( $member['member_id'] === \IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
$member['name'] = ( $member['member_id'] == $this->starter_id ) ? \IPS\Member::loggedIn()->language()->addToStack('participant_you_upper') : \IPS\Member::loggedIn()->language()->addToStack('participant_you_lower');
|
||||
}
|
||||
$people[ $member['member_id'] ] = $member['name'];
|
||||
}
|
||||
|
||||
/* Move the starter to the front of the array */
|
||||
$starter = $people[ $this->starter_id ];
|
||||
unset( $people[ $this->starter_id ] );
|
||||
array_unshift( $people, $starter );
|
||||
unset( $starter );
|
||||
|
||||
if ( count( $people ) == 1 )
|
||||
{
|
||||
$id = key( $people );
|
||||
$name = array_pop( $people );
|
||||
$this->participantBlurb = \IPS\Member::loggedIn()->member_id === $id ? \IPS\Member::loggedIn()->language()->addToStack( 'participant_you_upper' ) : $name;
|
||||
}
|
||||
elseif ( count( $people ) == 2 )
|
||||
{
|
||||
$this->participantBlurb = \IPS\Member::loggedIn()->language()->addToStack( 'participant_two', FALSE, array( 'sprintf' => $people ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$count = 0;
|
||||
$others = array();
|
||||
$sprintf = array();
|
||||
foreach( $people as $id => $name )
|
||||
{
|
||||
if ( $count > 1 )
|
||||
{
|
||||
$others[] = $name;
|
||||
}
|
||||
else
|
||||
{
|
||||
$sprintf[] = $name;
|
||||
}
|
||||
|
||||
$count++;
|
||||
}
|
||||
|
||||
$sprintf[] = \IPS\Member::loggedIn()->language()->formatList( $others );
|
||||
$sprintf[] = count( $others );
|
||||
|
||||
$this->participantBlurb = \IPS\Member::loggedIn()->language()->addToStack( 'participant_three_plus', FALSE, array( 'pluralize' => array( count( $others ) ), 'sprintf' => $sprintf ) );
|
||||
}
|
||||
|
||||
return $this->participantBlurb;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -171,6 +171,17 @@ class _Field extends \IPS\CustomField
|
||||
}
|
||||
|
||||
static::$editorOptions['autoSaveKey'] = md5( get_called_class() . '-' . $row['pf_id'] ) . ( isset( \IPS\Request::i()->id ) ? '-' . \IPS\Request::i()->id : '' );
|
||||
|
||||
if( $row['pf_type'] == 'Editor' )
|
||||
{
|
||||
static::$editorOptions['attachIds'] = array( ( isset( \IPS\Request::i()->id ) ? \IPS\Request::i()->id : 0 ), $row['pf_id'] );
|
||||
}
|
||||
|
||||
if ( $location === STAFF )
|
||||
{
|
||||
/* @link https://community.invisionpower.com/4bugtrack/active-reports/required-profile-fields-shouldnt-be-required-for-admins-r8058/ */
|
||||
$row['pf_not_null'] = 0;
|
||||
}
|
||||
|
||||
$return[ $groupId ][ $row['pf_id'] ] = static::constructFromData( $row )->buildHelper( $values[ 'field_' . $row['pf_id'] ] );
|
||||
}
|
||||
@@ -178,6 +189,32 @@ class _Field extends \IPS\CustomField
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load Record
|
||||
*
|
||||
* @see \IPS\Db::build
|
||||
* @param int|string $id ID
|
||||
* @param string $idField The database column that the $id parameter pertains to (NULL will use static::$databaseColumnId)
|
||||
* @param mixed $extraWhereClause Additional where clause(s) (see \IPS\Db::build for details)
|
||||
* @return static
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws \OutOfRangeException
|
||||
*/
|
||||
public static function load( $id, $idField=NULL, $extraWhereClause=NULL )
|
||||
{
|
||||
$result = parent::load( $id, $idField, $extraWhereClause );
|
||||
|
||||
static::$editorOptions['autoSaveKey'] = md5( get_called_class() . '-' . $result->id ) . ( isset( \IPS\Request::i()->id ) ? '-' . \IPS\Request::i()->id : '' );
|
||||
|
||||
if( $result->type == 'Editor' )
|
||||
{
|
||||
static::$editorOptions['attachIds'] = array( ( isset( \IPS\Request::i()->id ) ? \IPS\Request::i()->id : 0 ), $result->id );
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get Values
|
||||
|
||||
@@ -140,7 +140,7 @@ class _Facebook extends ProfileSyncAbstract
|
||||
if( isset( $statusData['message'] ) )
|
||||
{
|
||||
$status = \IPS\core\Statuses\Status::createItem( $this->member, $this->member->ip_address, new \IPS\DateTime( $statusData['updated_time'] ) );
|
||||
$status->content = nl2br( $statusData['message'], FALSE );
|
||||
$status->content = nl2br( \IPS\Text\Parser::utf8mb4SafeDecode( $statusData['message'] ), FALSE );
|
||||
return $status;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@ class _Google extends ProfileSyncAbstract
|
||||
if ( $status['object']['content'] )
|
||||
{
|
||||
$statusObj = \IPS\core\Statuses\Status::createItem( $this->member, $this->member->ip_address, new \IPS\DateTime( $status['published'] ) );
|
||||
$statusObj->content = nl2br( $status['object']['content'], FALSE );
|
||||
$statusObj->content = nl2br( \IPS\Text\Parser::utf8mb4SafeDecode( $status['object']['content'] ), FALSE );
|
||||
return $statusObj;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ abstract class _ProfileSyncAbstract
|
||||
$services = array();
|
||||
foreach ( new \DirectoryIterator( \IPS\ROOT_PATH . '/applications/core/sources/ProfileSync' ) as $file )
|
||||
{
|
||||
if ( !$file->isDot() and mb_substr( $file, -4 ) === '.php' )
|
||||
if ( !$file->isDot() and mb_substr( $file, -4 ) === '.php' and mb_substr( $file, 0, 2 ) != '._' )
|
||||
{
|
||||
require_once $file->getPathname();
|
||||
$class = 'IPS\core\ProfileSync\\' . mb_substr( $file, 0, -4 );
|
||||
@@ -173,6 +173,7 @@ abstract class _ProfileSyncAbstract
|
||||
*/
|
||||
public function save( $values )
|
||||
{
|
||||
/* Get existing settings */
|
||||
$settings = $this->member->profilesync ? json_decode( $this->member->profilesync, TRUE ) : array(
|
||||
static::$loginKey => array(
|
||||
'photo' => FALSE,
|
||||
@@ -180,12 +181,30 @@ abstract class _ProfileSyncAbstract
|
||||
'status' => ''
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
/* Set the new values for this service */
|
||||
$settings[ static::$loginKey ] = array(
|
||||
'photo' => isset( $values['profilesync_photo'] ) ? $values['profilesync_photo'] : ( isset( $settings[ static::$loginKey ]['photo'] ) ? $settings[ static::$loginKey ]['photo'] : FALSE ),
|
||||
'cover' => isset( $values['profilesync_cover'] ) ? $values['profilesync_cover'] : ( isset( $settings[ static::$loginKey ]['cover'] ) ? $settings[ static::$loginKey ]['cover'] : FALSE ),
|
||||
'status' => isset( $values['profilesync_status'] ) ? $values['profilesync_status'] : ( isset( $settings[ static::$loginKey ]['status'] ) ? $settings[ static::$loginKey ]['status'] : FALSE ),
|
||||
);
|
||||
'status' => isset( $values['profilesync_status'] ) ? ( $values['profilesync_status'] == 'none' ) ? FALSE : $values['profilesync_status'] : ( isset( $settings[ static::$loginKey ]['status'] ) ? $settings[ static::$loginKey ]['status'] : FALSE ),
|
||||
);
|
||||
|
||||
/* We cannot have more than one service syncing photos/cover photos - otherwise they conflict */
|
||||
foreach ( array( 'photo', 'cover' ) as $type )
|
||||
{
|
||||
if ( $settings[ static::$loginKey ][ $type ] )
|
||||
{
|
||||
foreach ( $settings as $service => $serviceSettings )
|
||||
{
|
||||
if ( $service != static::$loginKey and $serviceSettings[ $type ] )
|
||||
{
|
||||
$settings[ $service ][ $type ] = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Finalise */
|
||||
$this->member->profilesync = json_encode( $settings );
|
||||
|
||||
/* If we're enabling status import, reset last sync time so we import the latest status */
|
||||
@@ -227,7 +246,7 @@ abstract class _ProfileSyncAbstract
|
||||
}
|
||||
}
|
||||
}
|
||||
catch ( \IPS\Http\Request\Exception $e ) {}
|
||||
catch ( \RuntimeException $e ) {}
|
||||
}
|
||||
if ( $settings['cover'] and $this->member->group['gbw_allow_upload_bgimage'] )
|
||||
{
|
||||
@@ -240,9 +259,13 @@ abstract class _ProfileSyncAbstract
|
||||
catch ( \Exception $e ) { }
|
||||
}
|
||||
|
||||
$this->member->pp_cover_photo = (string) $this->cover();
|
||||
try
|
||||
{
|
||||
$this->member->pp_cover_photo = (string) $this->cover();
|
||||
}
|
||||
catch ( \RuntimeException $e ) {}
|
||||
}
|
||||
if ( $settings['status'] and $settings['status'] == 'import' )
|
||||
if ( $settings['status'] and $settings['status'] == 'import' and !$this->member->group['gbw_no_status_import'] )
|
||||
{
|
||||
if ( $status = $this->status() )
|
||||
{
|
||||
|
||||
@@ -161,7 +161,7 @@ class _Twitter extends ProfileSyncAbstract
|
||||
if ( isset( $user['status'] ) )
|
||||
{
|
||||
$status = \IPS\core\Statuses\Status::createItem( $this->member, $this->member->ip_address, new \IPS\DateTime( $user['status']['created_at'] ) );
|
||||
$status->content = $user['status']['text'];
|
||||
$status->content = \IPS\Text\Parser::utf8mb4SafeDecode( $user['status']['text'] );
|
||||
return $status;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,23 +34,24 @@ class _Install
|
||||
|
||||
/* PHP Version */
|
||||
$phpVersion = PHP_VERSION;
|
||||
if ( version_compare( PHP_VERSION, '5.3.0' ) >= 0 )
|
||||
if ( version_compare( $phpVersion, '5.3.0' ) >= 0 )
|
||||
{
|
||||
$return['requirements']['PHP'][] = array(
|
||||
$return['requirements']['PHP']['version'] = array(
|
||||
'success' => TRUE,
|
||||
'message' => \IPS\Member::loggedIn()->language()->addToStack( 'requirements_php_version_success', FALSE, array( 'sprintf' => array( $phpVersion ) ) )
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$return['requirements']['PHP'][] = array(
|
||||
$return['requirements']['PHP']['version'] = array(
|
||||
'success' => FALSE,
|
||||
'message' => \IPS\Member::loggedIn()->language()->addToStack( 'requirements_php_version_fail', FALSE, array( 'sprintf' => array( $phpVersion ) ) ),
|
||||
);
|
||||
}
|
||||
if ( version_compare( PHP_VERSION, '5.4.0' ) == -1 )
|
||||
if ( version_compare( $phpVersion, '5.4.0' ) == -1 )
|
||||
{
|
||||
$return['advice'][] = \IPS\Member::loggedIn()->language()->addToStack( 'requirements_php_version_advice', FALSE, array( 'sprintf' => array( $phpVersion ) ) );
|
||||
$return['requirements']['PHP']['version']['message'] = \IPS\Member::loggedIn()->language()->addToStack( 'requirements_php_version_success_53x', FALSE, array( 'sprintf' => array( $phpVersion ) ) );
|
||||
$return['advice']['php'] = \IPS\Member::loggedIn()->language()->addToStack( 'requirements_php_version_advice', FALSE, array( 'sprintf' => array( $phpVersion ) ) );
|
||||
}
|
||||
|
||||
/* cURL or allow_url_fopen */
|
||||
@@ -623,6 +624,7 @@ class _Install
|
||||
|
||||
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => $this->adminEmail ), "conf_key = 'email_out'" );
|
||||
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => $this->adminEmail ), "conf_key = 'email_in'" );
|
||||
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => $this->adminEmail ), "conf_key = 'upgrade_email'" );
|
||||
|
||||
unset( \IPS\Data\Store::i()->settings );
|
||||
|
||||
@@ -807,15 +809,15 @@ class _Install
|
||||
{
|
||||
return $this->appLoop( $data, function( $app )
|
||||
{
|
||||
if( !file_exists( \IPS\ROOT_PATH . '/plugins/hooks.txt' ) )
|
||||
if( !file_exists( \IPS\ROOT_PATH . '/plugins/hooks.php' ) )
|
||||
{
|
||||
@touch( \IPS\ROOT_PATH . '/plugins/hooks.txt' );
|
||||
@chmod( \IPS\ROOT_PATH . '/plugins/hooks.txt', 0777 );
|
||||
@touch( \IPS\ROOT_PATH . '/plugins/hooks.php' );
|
||||
@chmod( \IPS\ROOT_PATH . '/plugins/hooks.php', 0777 );
|
||||
}
|
||||
|
||||
if( !is_writable( \IPS\ROOT_PATH . '/plugins/hooks.txt' ) )
|
||||
if( !is_writable( \IPS\ROOT_PATH . '/plugins/hooks.php' ) )
|
||||
{
|
||||
throw new \RuntimeException( sprintf( \IPS\Member::loggedIn()->language()->get("hook_file_not_writable"), \IPS\ROOT_PATH . '/plugins/hooks.txt' ) );
|
||||
throw new \RuntimeException( sprintf( \IPS\Member::loggedIn()->language()->get("hook_file_not_writable"), \IPS\ROOT_PATH . '/plugins/hooks.php' ) );
|
||||
}
|
||||
|
||||
try
|
||||
@@ -842,16 +844,21 @@ class _Install
|
||||
|
||||
$inserts = array();
|
||||
|
||||
foreach( json_decode( file_get_contents( \IPS\ROOT_PATH . '/' . \IPS\CP_DIRECTORY ."/install/emoticons/data.json" ) ) as $type => $file )
|
||||
foreach( json_decode( file_get_contents( \IPS\ROOT_PATH . '/' . \IPS\CP_DIRECTORY ."/install/emoticons/data.json" ), TRUE ) as $type => $file )
|
||||
{
|
||||
$fileObj = \IPS\File::create( 'core_Emoticons', $file, file_get_contents( \IPS\ROOT_PATH . '/' . \IPS\CP_DIRECTORY . "/install/emoticons/" . $file ), 'emoticons', FALSE, NULL, FALSE );
|
||||
$fileObj = \IPS\File::create( 'core_Emoticons', $file['image'], file_get_contents( \IPS\ROOT_PATH . '/' . \IPS\CP_DIRECTORY . "/install/emoticons/" . $file['image'] ), 'emoticons', FALSE, NULL, FALSE );
|
||||
$fileObj2x = isset( $file['image_2x'] ) ? \IPS\File::create( 'core_Emoticons', $file['image_2x'], file_get_contents( \IPS\ROOT_PATH . '/' . \IPS\CP_DIRECTORY . "/install/emoticons/" . $file['image_2x'] ), 'emoticons', FALSE, NULL, FALSE ) : NULL;
|
||||
$imageProperties = @getimagesize( \IPS\ROOT_PATH . '/' . \IPS\CP_DIRECTORY . "/install/emoticons/" . $file['image'] );
|
||||
|
||||
$inserts[] = array(
|
||||
'typed' => $type,
|
||||
'image' => (string) $fileObj,
|
||||
'image_2x' => (string) $fileObj2x,
|
||||
'clickable' => TRUE,
|
||||
'emo_set' => $setId,
|
||||
'emo_position' => ++$position,
|
||||
'width' => isset( $imageProperties[0] ) ? $imageProperties[0] : 0,
|
||||
'height' => isset( $imageProperties[1] ) ? $imageProperties[1] : 0
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ class _Upgrade
|
||||
);
|
||||
}
|
||||
}
|
||||
catch ( \LogicException $e )
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
$fileSystemItems[ $class->configurationId ] = array(
|
||||
'success' => FALSE,
|
||||
@@ -673,15 +673,15 @@ class _Upgrade
|
||||
{
|
||||
return $this->appLoop( $data, function( $app )
|
||||
{
|
||||
if( !file_exists( \IPS\ROOT_PATH . '/plugins/hooks.txt' ) )
|
||||
if( !file_exists( \IPS\ROOT_PATH . '/plugins/hooks.php' ) )
|
||||
{
|
||||
@touch( \IPS\ROOT_PATH . '/plugins/hooks.txt' );
|
||||
@chmod( \IPS\ROOT_PATH . '/plugins/hooks.txt', 0777 );
|
||||
@touch( \IPS\ROOT_PATH . '/plugins/hooks.php' );
|
||||
@chmod( \IPS\ROOT_PATH . '/plugins/hooks.php', 0777 );
|
||||
}
|
||||
|
||||
if( !is_writable( \IPS\ROOT_PATH . '/plugins/hooks.txt' ) )
|
||||
if( !is_writable( \IPS\ROOT_PATH . '/plugins/hooks.php' ) )
|
||||
{
|
||||
throw new \RuntimeException( sprintf( \IPS\Member::loggedIn()->language()->get("hook_file_not_writable"), \IPS\ROOT_PATH . '/plugins/hooks.txt' ) );
|
||||
throw new \RuntimeException( sprintf( \IPS\Member::loggedIn()->language()->get("hook_file_not_writable"), \IPS\ROOT_PATH . '/plugins/hooks.php' ) );
|
||||
}
|
||||
|
||||
try
|
||||
|
||||
@@ -83,7 +83,7 @@ class _Service extends \IPS\Node\Model
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch All Services
|
||||
* Fetch All Nodes
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -102,6 +102,49 @@ class _Service extends \IPS\Node\Model
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch All Share Services
|
||||
*
|
||||
* @param \IPS\Http\Url $url URL to the content [optional - if omitted, some services will figure out on their own]
|
||||
* @param string $title Default text for the content, usually the title [optional - if omitted, some services will figure out on their own]
|
||||
* @param \IPS\Member|NULL $member Member the links will display to or NULL for currently logged in member
|
||||
* @return array
|
||||
*/
|
||||
public static function getAllServices( \IPS\Http\Url $url, $title, \IPS\Member $member = NULL )
|
||||
{
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
$services = array();
|
||||
foreach( static::shareLinks() as $node )
|
||||
{
|
||||
if( $node->enabled and ( $node->groups === "*" or $member->inGroup( explode( ',', $node->groups ) ) ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$services[ $node->key ] = $node->getService( $url, $title );
|
||||
}
|
||||
catch ( \LogicException $e ) { }
|
||||
}
|
||||
}
|
||||
return $services;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get \IPS\Content\ShareServices class
|
||||
*
|
||||
* @param \IPS\Http\Url $url URL to the content [optional - if omitted, some services will figure out on their own]
|
||||
* @param string $title Default text for the content, usually the title [optional - if omitted, some services will figure out on their own]
|
||||
* @return array
|
||||
*/
|
||||
public function getService( \IPS\Http\Url $url, $title )
|
||||
{
|
||||
if( file_exists( \IPS\ROOT_PATH . '/system/Content/ShareServices/' . ucwords( $this->key ) . '.php' ) )
|
||||
{
|
||||
$className = "IPS\\Content\\ShareServices\\" . ucwords( $this->key );
|
||||
return new $className( $url, $title );
|
||||
}
|
||||
throw new \LogicException;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Get buttons to display in tree
|
||||
|
||||
@@ -186,7 +186,7 @@ class _Group extends \IPS\Node\Model
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_members', array( 'member_group_id=?', $child->type_id ), 'name' ) as $m )
|
||||
foreach ( \IPS\Db::i()->select( '*', 'core_members', array( 'member_group_id=? OR FIND_IN_SET( ?, mgroup_others )', $child->type_id, $child->type_id ), 'name' ) as $m )
|
||||
{
|
||||
if ( !isset( $members[ $m['member_id'] ] ) )
|
||||
{
|
||||
|
||||
@@ -88,7 +88,7 @@ class _Reply extends \IPS\Content\Comment implements \IPS\Content\ReportCenter,
|
||||
/**
|
||||
* @brief [Content\Comment] Comment Template
|
||||
*/
|
||||
public static $commentTemplate = array( array( 'profile', 'core', 'front' ), 'statusReplyContainer' );
|
||||
public static $commentTemplate = array( array( 'statuses', 'core', 'front' ), 'statusReplyContainer' );
|
||||
|
||||
/**
|
||||
* @brief [Content] Key for hide reasons
|
||||
@@ -118,7 +118,7 @@ class _Reply extends \IPS\Content\Comment implements \IPS\Content\ReportCenter,
|
||||
if( !isset( $this->_url[ $_key ] ) )
|
||||
{
|
||||
$member = \IPS\Member::load( $this->item()->member_id );
|
||||
$this->_url[ $_key ] = \IPS\Http\Url::internal( "app=core&module=members&controller=profile&id={$member->member_id}&status={$this->id}", 'front', 'profile', array( $member->members_seo_name ) )->setQueryString( 'type', 'status' );
|
||||
$this->_url[ $_key ] = \IPS\Http\Url::internal( "app=core&module=members&controller=profile&id={$member->member_id}&status={$this->item()->id}&reply={$this->id}", 'front', 'profile', array( $member->members_seo_name ) )->setQueryString( 'type', 'status' );
|
||||
|
||||
if ( $action )
|
||||
{
|
||||
@@ -185,4 +185,14 @@ class _Reply extends \IPS\Content\Comment implements \IPS\Content\ReportCenter,
|
||||
|
||||
return parent::canDelete( $member );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get template for content tables
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
public static function contentTableTemplate()
|
||||
{
|
||||
return array( \IPS\Theme::i()->getTemplate( 'statuses', 'core' ), 'statusReplyContentRows' );
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
/**
|
||||
* Status Update Model
|
||||
*/
|
||||
class _Status extends \IPS\Content\Item implements \IPS\Content\ReportCenter, \IPS\Content\Reputation, \IPS\Content\Lockable, \IPS\Content\Hideable
|
||||
class _Status extends \IPS\Content\Item implements \IPS\Content\ReportCenter, \IPS\Content\Reputation, \IPS\Content\Lockable, \IPS\Content\Hideable, \IPS\Content\Searchable
|
||||
{
|
||||
/* !\IPS\Patterns\ActiveRecord */
|
||||
|
||||
@@ -55,6 +55,21 @@ class _Status extends \IPS\Content\Item implements \IPS\Content\ReportCenter, \I
|
||||
*/
|
||||
protected static $multitons;
|
||||
|
||||
/**
|
||||
* @brief [Content\Item] Include the ability to search this content item in global site searches
|
||||
*/
|
||||
public static $includeInSiteSearch = FALSE;
|
||||
|
||||
/**
|
||||
* Columns needed to query for search result / stream view
|
||||
*
|
||||
* @return array|string
|
||||
*/
|
||||
public static function basicDataColumns()
|
||||
{
|
||||
return '*';
|
||||
}
|
||||
|
||||
/**
|
||||
* Save Changed Columns
|
||||
*
|
||||
@@ -164,6 +179,16 @@ class _Status extends \IPS\Content\Item implements \IPS\Content\ReportCenter, \I
|
||||
return strip_tags( $this->mapped('content') );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get container ID for search index
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function searchIndexContainer()
|
||||
{
|
||||
return $this->member_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mapped value
|
||||
*
|
||||
@@ -174,7 +199,8 @@ class _Status extends \IPS\Content\Item implements \IPS\Content\ReportCenter, \I
|
||||
{
|
||||
if ( $key === 'title' )
|
||||
{
|
||||
return $this->title;
|
||||
/* We do not want the content (which is mapped to title in $databaseColumnMap) to be added into core_search_index.index_title as the field is only varchar(255) */
|
||||
return mb_substr( $this->title, 0, 85 );
|
||||
}
|
||||
|
||||
return parent::mapped( $key );
|
||||
@@ -204,20 +230,33 @@ class _Status extends \IPS\Content\Item implements \IPS\Content\ReportCenter, \I
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Disabled at the group level? */
|
||||
if( \IPS\Member::loggedIn()->group['gbw_no_status_update'] )
|
||||
|
||||
if ( $member->pp_setting_count_comments === 0 or !\IPS\Settings::i()->profile_comments )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Or at the profile level? */
|
||||
if( \IPS\Member::loggedIn()->members_bitoptions['bw_no_status_update'] )
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can a given member reply to a status update?
|
||||
*
|
||||
* @param \IPS\Member $member The member
|
||||
* @param \IPS\Node\Model|NULL $container Container
|
||||
* @param bool $showError If TRUE, rather than returning a boolean value, will display an error
|
||||
* @return bool
|
||||
*/
|
||||
public static function canCreateReply( \IPS\Member $member, \IPS\Node\Model $container=NULL, $showError=FALSE )
|
||||
{
|
||||
/* Can we access the module? */
|
||||
if ( !parent::canCreate( $member, $container, $showError ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( !$member->pp_setting_count_comments or !\IPS\Settings::i()->profile_comments )
|
||||
/* We have to be logged in */
|
||||
if ( !$member->member_id )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -249,25 +288,19 @@ class _Status extends \IPS\Content\Item implements \IPS\Content\ReportCenter, \I
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* And not restricted */
|
||||
if ( $member->members_bitoptions['bw_no_status_update'] )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Is the user being ignored */
|
||||
if ( $profileOwner->isIgnoring( $member, 'messages' ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Disabled at the group level? */
|
||||
if( \IPS\Member::loggedIn()->group['gbw_no_status_update'] )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Or at the profile level? */
|
||||
if( \IPS\Member::loggedIn()->members_bitoptions['bw_no_status_update'] )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( !$profileOwner->pp_setting_count_comments and $member->member_id != \IPS\Request::i()->id )
|
||||
if ( $profileOwner->pp_setting_count_comments === 0 )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -375,9 +408,9 @@ class _Status extends \IPS\Content\Item implements \IPS\Content\ReportCenter, \I
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Cached URLs
|
||||
* @brief Cached URL
|
||||
*/
|
||||
protected $_url = array();
|
||||
protected $_url = NULL;
|
||||
|
||||
/**
|
||||
* Get URL
|
||||
@@ -387,32 +420,31 @@ class _Status extends \IPS\Content\Item implements \IPS\Content\ReportCenter, \I
|
||||
*/
|
||||
public function url( $action=NULL )
|
||||
{
|
||||
$_key = md5( $action );
|
||||
|
||||
if( !isset( $this->_url[ $_key ] ) )
|
||||
if( $this->_url === NULL )
|
||||
{
|
||||
$member = \IPS\Member::load( $this->member_id );
|
||||
$this->_url[ $_key ] = \IPS\Http\Url::internal( "app=core&module=members&controller=profile&id={$member->member_id}&status={$this->id}&type=status", 'front', 'profile', array( $member->members_seo_name ) );
|
||||
$this->_url = \IPS\Http\Url::internal( "app=core&module=members&controller=profile&id={$member->member_id}&status={$this->id}&type=status", 'front', 'profile', array( $member->members_seo_name ) );
|
||||
}
|
||||
|
||||
if ( $action )
|
||||
$return = $this->_url;
|
||||
if ( $action )
|
||||
{
|
||||
if ( $action == 'edit' )
|
||||
{
|
||||
if ( $action == 'edit' )
|
||||
{
|
||||
$this->_url[ $_key ] = $this->_url[ $_key ]->setQueryString( 'do', 'editStatus' );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->_url[ $_key ] = $this->_url[ $_key ]->setQueryString( array( 'do' => $action, 'type' => 'status' ) );
|
||||
}
|
||||
$return = $return->setQueryString( 'do', 'editStatus' );
|
||||
}
|
||||
else
|
||||
{
|
||||
$return = $return->setQueryString( array( 'do' => $action, 'type' => 'status' ) );
|
||||
}
|
||||
|
||||
if ( $action == 'moderate' AND \IPS\Request::i()->controller == 'feed' )
|
||||
{
|
||||
$this->_url[ $_key ] = $this->_url[ $_key ]->setQueryString( '_fromFeed', 1 );
|
||||
}
|
||||
if ( $action == 'moderate' AND \IPS\Request::i()->controller == 'feed' )
|
||||
{
|
||||
$return = $return->setQueryString( '_fromFeed', 1 );
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_url[ $_key ];
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -553,7 +585,33 @@ class _Status extends \IPS\Content\Item implements \IPS\Content\ReportCenter, \I
|
||||
*/
|
||||
public static function contentTableTemplate()
|
||||
{
|
||||
return array( \IPS\Theme::i()->getTemplate( 'profile', 'core' ), 'statusContentRows' );
|
||||
return array( \IPS\Theme::i()->getTemplate( 'statuses', 'core' ), 'statusContentRows' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get 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 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 static function searchResult( array $indexData, array $authorData, array $itemData, array $containerData = NULL, array $reputationData, $reviewRating, $iPostedIn, $view, $asItem )
|
||||
{
|
||||
$status = static::constructFromData( $itemData );
|
||||
$status->reputation = $reputationData;
|
||||
|
||||
$profileOwner = isset( $itemData['profile'] ) ? $itemData['profile'] : NULL;
|
||||
$profileOwnerData = $profileOwner ?: $authorData;
|
||||
$status->_url = \IPS\Http\Url::internal( "app=core&module=members&controller=profile&id={$profileOwnerData['member_id']}&status={$itemData['status_id']}&type=status", 'front', 'profile', array( $profileOwnerData['members_seo_name'] ) );
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'statuses', 'core', 'front' )->statusContainer( $status, $authorData, $profileOwner, $view == 'condensed' );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,802 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Content Discovery Stream
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @since 1 Jul 2015
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\core;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Content Discovery Stream
|
||||
*/
|
||||
class _Stream extends \IPS\Node\Model
|
||||
{
|
||||
/**
|
||||
* @brief [ActiveRecord] Multiton Store
|
||||
*/
|
||||
protected static $multitons;
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Table
|
||||
*/
|
||||
public static $databaseTable = 'core_streams';
|
||||
|
||||
/**
|
||||
* @brief [Node] Order Database Column
|
||||
*/
|
||||
public static $databaseColumnOrder = 'position';
|
||||
|
||||
/**
|
||||
* @brief [Node] Node Title
|
||||
*/
|
||||
public static $nodeTitle = 'streams';
|
||||
|
||||
/**
|
||||
* @brief [Node] Title prefix. If specified, will look for a language key with "{$key}_title" as the key
|
||||
*/
|
||||
public static $titleLangPrefix = 'stream_title_';
|
||||
|
||||
/**
|
||||
* @brief [Node] ACP Restrictions
|
||||
* @code
|
||||
array(
|
||||
'app' => 'core', // The application key which holds the restrictrions
|
||||
'module' => 'foo', // The module key which holds the restrictions
|
||||
'map' => array( // [Optional] The key for each restriction - can alternatively use "prefix"
|
||||
'add' => 'foo_add',
|
||||
'edit' => 'foo_edit',
|
||||
'permissions' => 'foo_perms',
|
||||
'delete' => 'foo_delete'
|
||||
),
|
||||
'all' => 'foo_manage', // [Optional] The key to use for any restriction not provided in the map (only needed if not providing all 4)
|
||||
'prefix' => 'foo_', // [Optional] Rather than specifying each key in the map, you can specify a prefix, and it will automatically look for restrictions with the key "[prefix]_add/edit/permissions/delete"
|
||||
* @encode
|
||||
*/
|
||||
protected static $restrictions = array(
|
||||
'app' => 'core',
|
||||
'module' => 'discovery',
|
||||
'all' => 'streams_manage',
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief The default stream either set by member or admin
|
||||
*/
|
||||
protected static $defaultStream = NULL;
|
||||
|
||||
/**
|
||||
* Fetch All Root 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 roots( $permissionCheck='view', $member=NULL, $where=array() )
|
||||
{
|
||||
$where[] = array( 'member IS NULL' );
|
||||
return parent::roots( $permissionCheck, $member, $where );
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the default stream, or NULL
|
||||
*
|
||||
* @return \IPS\core\Stream|null
|
||||
*/
|
||||
public static function defaultStream()
|
||||
{
|
||||
/* Check the member first */
|
||||
if ( \IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
$default = \IPS\Member::loggedIn()->defaultStream;
|
||||
|
||||
if ( $default !== NULL )
|
||||
{
|
||||
try
|
||||
{
|
||||
if ( $default )
|
||||
{
|
||||
return static::load( $default );
|
||||
}
|
||||
else
|
||||
{
|
||||
return static::allActivityStream();
|
||||
}
|
||||
}
|
||||
catch( \Exception $e )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Still here? Check menu */
|
||||
try
|
||||
{
|
||||
return static::load( \IPS\Db::i()->select( 'id', 'core_streams', array( array( '`default`=?', 1 ) ) )->first() );
|
||||
}
|
||||
catch( \Exception $e )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* "All Activity" Stream
|
||||
*
|
||||
* @return \IPS\core\Stream
|
||||
*/
|
||||
public static function allActivityStream()
|
||||
{
|
||||
$stream = new static;
|
||||
$stream->id = 0;
|
||||
$stream->include_comments = TRUE;
|
||||
return $stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Get Title
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
protected function get__title()
|
||||
{
|
||||
if ( $this->id )
|
||||
{
|
||||
return $this->title ?: parent::get__title();
|
||||
}
|
||||
else
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('all_activity');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Add/Edit Form
|
||||
*
|
||||
* @param \IPS\Helpers\Form $form The form
|
||||
* @param string $titleType 'Text' or 'Translatable
|
||||
* @pram bool $titleRequired Is the title field required?
|
||||
* @return void
|
||||
*/
|
||||
public function form( &$form, $titleType='Translatable', $titleRequired=TRUE )
|
||||
{
|
||||
/* Title */
|
||||
if ( $titleType )
|
||||
{
|
||||
$titleClass = '\IPS\Helpers\Form\\' . $titleType;
|
||||
$form->add( new $titleClass( 'stream_title', ( $this->id and $titleType === 'Text' ) ? $this->_title : NULL, $titleRequired, array( 'app' => 'core', 'key' => ( $this->id ? "stream_title_{$this->id}" : NULL ) ) ) );
|
||||
}
|
||||
|
||||
/* All content or specific content? */
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'stream_include_comments', $this->include_comments, TRUE, array( 'options' => array(
|
||||
1 => 'stream_include_comments_1',
|
||||
0 => 'stream_include_comments_0'
|
||||
) ) ) );
|
||||
|
||||
/* All content or specific content? */
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'stream_classes_type', $this->classes ? 1 : 0, TRUE, array(
|
||||
'options' => array( 0 => 'stream_classes_type_all', 1 => 'stream_classes_type_custom' ),
|
||||
'toggles' => array( 1 => array( 'stream_classes' ) )
|
||||
) ) );
|
||||
|
||||
/* Work out all the different classes */
|
||||
$classes = array();
|
||||
$classContainers = array();
|
||||
$classToggles = array();
|
||||
foreach ( \IPS\Content::routedClasses( TRUE, FALSE, TRUE ) as $class )
|
||||
{
|
||||
$classes[ $class ] = $class::$title . '_pl';
|
||||
if ( isset( $class::$containerNodeClass ) )
|
||||
{
|
||||
$classContainers[] = $class;
|
||||
$classToggles[ $class ][] = 'stream_containers_' . $class::$title;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add the fields for them */
|
||||
$currentContainers = $this->containers ? json_decode( $this->containers, TRUE ) : array();
|
||||
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'stream_classes', $this->classes ? explode( ',', $this->classes ) : array(), NULL, array( 'options' => $classes, 'toggles' => $classToggles ), NULL, NULL, NULL, 'stream_classes' ) );
|
||||
foreach ( $classContainers as $class )
|
||||
{
|
||||
$field = new \IPS\Helpers\Form\Node( 'stream_containers_' . $class::$title, isset( $currentContainers[ $class ] ) ? $currentContainers[ $class ] : array(), NULL, array( 'class' => $class::$containerNodeClass, 'multiple' => TRUE, 'permissionCheck' => 'view' ), NULL, NULL, NULL, 'stream_containers_' . $class::$title );
|
||||
$containerClass = $class::$containerNodeClass;
|
||||
$field->label = \IPS\Member::loggedIn()->language()->addToStack( $containerClass::$nodeTitle );
|
||||
$form->add( $field );
|
||||
}
|
||||
|
||||
/* Tags */
|
||||
if ( \IPS\Settings::i()->tags_enabled )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'stream_tags_type', $this->tags ? 'custom' : 'all', TRUE, array(
|
||||
'options' => array(
|
||||
'all' => 'stream_tags_all',
|
||||
'custom' => 'stream_tags_custom'
|
||||
),
|
||||
'toggles' => array(
|
||||
'custom' => array( 'stream_tags' )
|
||||
)
|
||||
) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'stream_tags', $this->tags ? explode( ',', $this->tags ) : NULL, NULL, array( 'autocomplete' => array() ), NULL, NULL, NULL, 'stream_tags' ) );
|
||||
}
|
||||
|
||||
/* Ownership */
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'stream_ownership', $this->ownership, TRUE, array(
|
||||
'options' => array(
|
||||
'all' => 'stream_ownership_all',
|
||||
'started' => 'stream_ownership_started',
|
||||
'postedin' => 'stream_ownership_postedin',
|
||||
'custom' => 'stream_ownership_custom',
|
||||
),
|
||||
'toggles' => array(
|
||||
'custom' => array( 'stream_custom_members' )
|
||||
)
|
||||
) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Member( 'stream_custom_members', $this->custom_members ? array_map( array( 'IPS\Member', 'load' ), explode( ',', $this->custom_members ) ) : NULL, NULL, array( 'multiple' => NULL ), NULL, NULL, NULL, 'stream_custom_members' ) );
|
||||
|
||||
/* Read */
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'stream_read', $this->read, TRUE, array( 'options' => array(
|
||||
'all' => 'stream_read_all',
|
||||
'unread' => 'stream_read_unread',
|
||||
) ) ) );
|
||||
|
||||
/* Follow */
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'stream_follow', $this->follow, TRUE, array(
|
||||
'options' => array(
|
||||
'all' => 'stream_follow_all',
|
||||
'followed' => 'stream_follow_followed',
|
||||
),
|
||||
'toggles' => array(
|
||||
'followed' => array( 'stream_followed_types' )
|
||||
)
|
||||
) ) );
|
||||
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'stream_followed_types', $this->followed_type ? explode( ',', $this->followed_types ) : array( 'items' ), NULL, array( 'options' => array(
|
||||
'containers' => 'stream_followed_types_areas',
|
||||
'items' => 'stream_followed_types_items',
|
||||
'members' => 'stream_followed_types_members',
|
||||
) ), NULL, NULL, NULL, 'stream_followed_types' ) );
|
||||
|
||||
/* Date */
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'stream_date_type', $this->date_type, TRUE, array(
|
||||
'options' => array(
|
||||
'all' => 'stream_date_type_all',
|
||||
'last_visit' => 'stream_date_type_last_visit',
|
||||
'relative' => 'stream_date_type_relative',
|
||||
'custom' => 'stream_date_type_custom',
|
||||
),
|
||||
'toggles' => array(
|
||||
'relative' => array( 'stream_date_relative_days' ),
|
||||
'custom' => array( 'stream_date_range' )
|
||||
)
|
||||
) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'stream_date_relative_days', $this->date_relative_days ?: 7, NULL, array(), function( $val )
|
||||
{
|
||||
if ( \IPS\Request::i()->stream_date_type == 'relative' and !$val )
|
||||
{
|
||||
throw new \DomainException('form_required');
|
||||
}
|
||||
}, \IPS\Member::loggedIn()->language()->addToStack('stream_date_relative_days_prefix'), \IPS\Member::loggedIn()->language()->addToStack('days'), 'stream_date_relative_days' ) );
|
||||
$form->add( new \IPS\Helpers\Form\DateRange( 'stream_date_range', array( 'start' => $this->date_start, 'end' => $this->date_end ), NULL, array(), function( $val )
|
||||
{
|
||||
if ( \IPS\Request::i()->stream_date_type == 'custom' and !$val['start'] and !$val['end'] )
|
||||
{
|
||||
throw new \DomainException('form_required');
|
||||
}
|
||||
}, NULL, NULL, 'stream_date_range' ) );
|
||||
|
||||
/* Sort */
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'stream_sort', $this->sort, TRUE, array( 'options' => array(
|
||||
'newest' => 'stream_sort_newest',
|
||||
'oldest' => 'stream_sort_oldest',
|
||||
) ) ) );
|
||||
|
||||
if ( \IPS\Dispatcher::i()->controllerLocation === 'admin' )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'stream_default', $this->default, FALSE ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Format form values from add/edit form for save
|
||||
*
|
||||
* @param array $values Values from the form
|
||||
* @return array
|
||||
*/
|
||||
public function formatFormValues( $values )
|
||||
{
|
||||
/* Title */
|
||||
if ( !$this->id )
|
||||
{
|
||||
$this->save();
|
||||
}
|
||||
if ( isset( $values['stream_title'] ) and is_array( $values['stream_title'] ) )
|
||||
{
|
||||
\IPS\Lang::saveCustom( 'core', "stream_title_{$this->id}", $values['stream_title'] );
|
||||
$values['stream_title'] = NULL;
|
||||
}
|
||||
unset( $values['__custom_stream'] );
|
||||
|
||||
/* Sort out stream_classes_type */
|
||||
if ( $values['stream_classes_type'] )
|
||||
{
|
||||
$classes = array();
|
||||
$containers = NULL;
|
||||
foreach ( $values['stream_classes'] as $class )
|
||||
{
|
||||
$classes[] = $class;
|
||||
if ( isset( $values[ 'stream_containers_' . $class::$title ] ) and $values[ 'stream_containers_' . $class::$title ] )
|
||||
{
|
||||
$containers[ $class ] = array_keys( $values[ 'stream_containers_' . $class::$title ] );
|
||||
}
|
||||
}
|
||||
|
||||
$values['stream_classes'] = implode( ',', $classes );
|
||||
$values['stream_containers'] = $containers ? json_encode( $containers ) : NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
$values['stream_classes'] = NULL;
|
||||
$values['stream_containers'] = NULL;
|
||||
}
|
||||
unset( $values['stream_classes_type'] );
|
||||
|
||||
/* And tags */
|
||||
if ( $values['stream_tags_type'] == 'all' or !$values['stream_tags'] )
|
||||
{
|
||||
$values['stream_tags'] = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
$values['stream_tags'] = implode( ',', $values['stream_tags'] );
|
||||
}
|
||||
unset( $values['stream_tags_type'] );
|
||||
|
||||
/* And follows */
|
||||
$values['stream_followed_types'] = ( $values['stream_follow'] == 'followed' ? implode( ',', $values['stream_followed_types'] ) : NULL );
|
||||
|
||||
/* And members */
|
||||
if ( $values['stream_ownership'] == 'custom' )
|
||||
{
|
||||
$members = array();
|
||||
foreach ( $values['stream_custom_members'] as $member )
|
||||
{
|
||||
$members[] = $member->member_id;
|
||||
}
|
||||
$values['stream_custom_members'] = implode( ',', $members );
|
||||
}
|
||||
else
|
||||
{
|
||||
$values['stream_custom_members'] = NULL;
|
||||
}
|
||||
|
||||
/* And dates */
|
||||
if ( $values['stream_date_type'] )
|
||||
{
|
||||
$values['stream_date_start'] = $values['stream_date_range']['start'] ? $values['stream_date_range']['start']->getTimestamp() : NULL;
|
||||
$values['stream_date_end'] = $values['stream_date_range']['end'] ? $values['stream_date_range']['end']->getTimestamp() : NULL;
|
||||
}
|
||||
unset( $values['stream_date_range'] );
|
||||
|
||||
if ( \IPS\Dispatcher::i()->controllerLocation === 'admin' and ! empty( $values['stream_default'] ) )
|
||||
{
|
||||
$where = ( $this->id ) ? array( 'id !=?', $this->id ) : NULL;
|
||||
\IPS\Db::i()->update( 'core_streams', array( 'default' => 0 ), $where );
|
||||
}
|
||||
|
||||
/* Remove stream_ prefix */
|
||||
$_values = $values;
|
||||
$values = array();
|
||||
foreach ( $_values as $k => $v )
|
||||
{
|
||||
if( mb_substr( $k, 0, 15 ) === 'stream_classes_' or mb_substr( $k, 0, 18 ) === 'stream_containers_' )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if( mb_substr( $k, 0, 7 ) === 'stream_' )
|
||||
{
|
||||
$values[ mb_substr( $k, 7 ) ] = $v;
|
||||
}
|
||||
else
|
||||
{
|
||||
$values[ $k ] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return */
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get blurb
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function blurb()
|
||||
{
|
||||
if ( $this->classes )
|
||||
{
|
||||
$classes = array();
|
||||
foreach ( explode( ',', $this->classes ) as $class )
|
||||
{
|
||||
if ( class_exists( $class ) )
|
||||
{
|
||||
if ( in_array( 'IPS\Content\Review', class_parents( $class ) ) )
|
||||
{
|
||||
$classes[ $class::$itemClass ]['reviews'] = $class;
|
||||
}
|
||||
elseif ( in_array( 'IPS\Content\Comment', class_parents( $class ) ) )
|
||||
{
|
||||
$classes[ $class::$itemClass ]['comments'] = $class;
|
||||
}
|
||||
elseif ( in_array( 'IPS\Content\Item', class_parents( $class ) ) )
|
||||
{
|
||||
$classes[ $class ]['items'] = $class;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$types = array();
|
||||
$allowedContainers = $this->containers ? json_decode( $this->containers, TRUE ) : array();
|
||||
foreach ( $classes as $itemClass => $subClasses )
|
||||
{
|
||||
$_types = array();
|
||||
foreach ( $subClasses as $class )
|
||||
{
|
||||
$_types[] = \IPS\Member::loggedIn()->language()->addToStack( $class::$title . '_pl', FALSE, array( 'strtolower' => TRUE ) );
|
||||
}
|
||||
$_types = \IPS\Member::loggedIn()->language()->formatList( $_types );
|
||||
|
||||
if ( isset( $allowedContainers[ $itemClass ] ) )
|
||||
{
|
||||
$containers = array();
|
||||
$containerClass = $itemClass::$containerNodeClass;
|
||||
foreach ( $allowedContainers[ $itemClass ] as $id )
|
||||
{
|
||||
try
|
||||
{
|
||||
$containers[] = $containerClass::loadAndCheckPerms( $id )->_title;
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
}
|
||||
$containers = \IPS\Member::loggedIn()->language()->formatList( $containers );
|
||||
|
||||
$types[] = \IPS\Member::loggedIn()->language()->addToStack( 'stream_blurb_in_containers', FALSE, array( 'sprintf' => array( $_types, $containers ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$types[] = $_types;
|
||||
}
|
||||
}
|
||||
|
||||
$type = \IPS\Member::loggedIn()->language()->formatList( $types );
|
||||
}
|
||||
else
|
||||
{
|
||||
$type = \IPS\Member::loggedIn()->language()->addToStack('stream_blurb_all');
|
||||
}
|
||||
|
||||
$terms = array();
|
||||
|
||||
if ( $this->tags )
|
||||
{
|
||||
$terms[] = \IPS\Member::loggedIn()->language()->addToStack( 'stream_includes_tags', FALSE, array( 'sprintf' => \IPS\Member::loggedIn()->language()->formatList( array_map( function( $val ){
|
||||
return '\'' . $val . '\'';
|
||||
}, explode( ',', $this->tags ) ), \IPS\Member::loggedIn()->language()->get('or_list_format') ) ) );
|
||||
}
|
||||
|
||||
switch ( $this->ownership )
|
||||
{
|
||||
case 'started':
|
||||
$terms[] = \IPS\Member::loggedIn()->language()->addToStack('stream_blurb_i_started');
|
||||
break;
|
||||
|
||||
case 'postedin':
|
||||
$terms[] = \IPS\Member::loggedIn()->language()->addToStack('stream_blurb_i_posted_in');
|
||||
break;
|
||||
|
||||
case 'custom':
|
||||
$memberNames = array();
|
||||
foreach ( explode( ',', $this->custom_members ) as $memberId )
|
||||
{
|
||||
$_member = \IPS\Member::load( $memberId );
|
||||
if ( $_member->member_id )
|
||||
{
|
||||
$memberNames[] = $_member->name;
|
||||
}
|
||||
}
|
||||
$terms[] = \IPS\Member::loggedIn()->language()->addToStack( 'stream_blurb_by_members', FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->formatList( $memberNames, \IPS\Member::loggedIn()->language()->get('or_list_format') ) ) ) );
|
||||
break;
|
||||
}
|
||||
if ( $this->read == 'unread' )
|
||||
{
|
||||
$terms[] = \IPS\Member::loggedIn()->language()->addToStack('stream_blurb_unread');
|
||||
}
|
||||
if ( $this->follow == 'followed' )
|
||||
{
|
||||
$followTerms = array();
|
||||
foreach ( explode( ',', $this->followed_types ) as $followType )
|
||||
{
|
||||
switch ( $followType )
|
||||
{
|
||||
case 'containers':
|
||||
$followTerms[] = \IPS\Member::loggedIn()->language()->addToStack('stream_blurb_following_containers');
|
||||
break;
|
||||
case 'items':
|
||||
$followTerms[] = \IPS\Member::loggedIn()->language()->addToStack('stream_blurb_following_items');
|
||||
break;
|
||||
case 'members':
|
||||
$followTerms[] = \IPS\Member::loggedIn()->language()->addToStack('stream_blurb_following_members');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$terms[] = \IPS\Member::loggedIn()->language()->formatList( $followTerms, \IPS\Member::loggedIn()->language()->get('or_list_format') );
|
||||
}
|
||||
switch ( $this->date_type )
|
||||
{
|
||||
case 'last_visit':
|
||||
$terms[] = \IPS\Member::loggedIn()->language()->addToStack('stream_blurb_since_last_visit');
|
||||
break;
|
||||
case 'relative':
|
||||
$terms[] = \IPS\Member::loggedIn()->language()->addToStack( 'stream_blurb_relative', FALSE, array( 'sprintf' => array( $this->date_relative_days ) ) );
|
||||
break;
|
||||
case 'custom':
|
||||
if ( $this->date_start and $this->date_end )
|
||||
{
|
||||
$terms[] = \IPS\Member::loggedIn()->language()->addToStack( 'stream_blurb_date_between', FALSE, array( 'sprintf' => array( \IPS\DateTime::ts( $this->date_start ), \IPS\DateTime::ts( $this->date_end ) ) ) );
|
||||
}
|
||||
elseif ( $this->date_start )
|
||||
{
|
||||
$terms[] = \IPS\Member::loggedIn()->language()->addToStack( 'stream_blurb_date_after', FALSE, array( 'sprintf' => array( \IPS\DateTime::ts( $this->date_start ) ) ) );
|
||||
}
|
||||
elseif ( $this->date_end )
|
||||
{
|
||||
$terms[] = \IPS\Member::loggedIn()->language()->addToStack( 'stream_blurb_date_before', FALSE, array( 'sprintf' => array( \IPS\DateTime::ts( $this->date_end ) ) ) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ( count( $terms ) )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'steam_blurb_with_terms', FALSE, array( 'sprintf' => array( $type, \IPS\Member::loggedIn()->language()->formatList( $terms ) ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'steam_blurb_no_terms', FALSE, array( 'sprintf' => array( $type ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get results
|
||||
*
|
||||
* @param \IPS\Member|null $member The member to get the results as
|
||||
* @return \IPS\Content\Search\Query
|
||||
*/
|
||||
public function query( $member = NULL )
|
||||
{
|
||||
/* Init */
|
||||
$query = \IPS\Content\Search\Query::init( $member );
|
||||
|
||||
/* Content Filters */
|
||||
$filters = array();
|
||||
$allowedContainers = $this->containers ? json_decode( $this->containers, TRUE ) : array();
|
||||
if ( $this->classes )
|
||||
{
|
||||
/* Translate how we store this into the format needed for filterByContent */
|
||||
$classes = array();
|
||||
foreach ( explode( ',', $this->classes ) as $class )
|
||||
{
|
||||
if ( class_exists( $class ) )
|
||||
{
|
||||
$classes[ $class ]['items'] = TRUE;
|
||||
if ( $this->include_comments and isset( $class::$commentClass ) )
|
||||
{
|
||||
$classes[ $class ]['comments'] = TRUE;
|
||||
}
|
||||
if ( $this->include_comments and isset( $class::$reviewClass ) )
|
||||
{
|
||||
$classes[ $class ]['reviews'] = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Build the filters */
|
||||
foreach ( $classes as $class => $options )
|
||||
{
|
||||
/* Init */
|
||||
if ( isset( $options['items'] ) and !isset( $options['comments'] ) and in_array( 'IPS\Content\Item', class_parents( $class ) ) and $class::$firstCommentRequired )
|
||||
{
|
||||
$filter = \IPS\Content\Search\ContentFilter::init( $class, TRUE, TRUE, isset( $options['reviews'] ) )->onlyLastComment();
|
||||
}
|
||||
else
|
||||
{
|
||||
$filter = \IPS\Content\Search\ContentFilter::init( $class, isset( $options['items'] ), isset( $options['comments'] ), isset( $options['reviews'] ) );
|
||||
}
|
||||
|
||||
/* Are we restricted to certain containers? */
|
||||
if ( isset( $allowedContainers[ $class ] ) )
|
||||
{
|
||||
$filter->onlyInContainers( $allowedContainers[ $class ] );
|
||||
}
|
||||
|
||||
/* Add to the array */
|
||||
$filters[] = $filter;
|
||||
}
|
||||
}
|
||||
elseif ( !$this->include_comments )
|
||||
{
|
||||
foreach ( \IPS\Application::allExtensions( 'core', 'ContentRouter', FALSE ) as $object )
|
||||
{
|
||||
foreach ( $object->classes as $class )
|
||||
{
|
||||
if ( in_array( 'IPS\Content\Item', class_parents( $class ) ) )
|
||||
{
|
||||
if ( $class::$firstCommentRequired )
|
||||
{
|
||||
$filters[] = \IPS\Content\Search\ContentFilter::init( $class, TRUE, TRUE, FALSE )->onlyLastComment();
|
||||
}
|
||||
else
|
||||
{
|
||||
$filters[] = \IPS\Content\Search\ContentFilter::init( $class, TRUE, FALSE, FALSE );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( count( $filters ) )
|
||||
{
|
||||
$query->filterByContent( $filters );
|
||||
}
|
||||
|
||||
/* Ownership */
|
||||
switch ( $this->ownership )
|
||||
{
|
||||
case 'started':
|
||||
$query->filterByItemAuthor( \IPS\Member::loggedIn() );
|
||||
break;
|
||||
|
||||
case 'postedin':
|
||||
$query->filterByItemsIPostedIn();
|
||||
break;
|
||||
|
||||
case 'custom':
|
||||
$query->filterByAuthor( explode( ',', $this->custom_members ) );
|
||||
break;
|
||||
}
|
||||
|
||||
/* Read */
|
||||
if ( $this->read == 'unread' )
|
||||
{
|
||||
$query->filterByUnread();
|
||||
}
|
||||
|
||||
/* Follow */
|
||||
if ( $this->follow == 'followed' )
|
||||
{
|
||||
$followTypes = explode( ',', $this->followed_types );
|
||||
$query->filterByFollowed( in_array( 'containers', $followTypes ), in_array( 'items', $followTypes ), in_array( 'members', $followTypes ) );
|
||||
}
|
||||
|
||||
/* Date */
|
||||
switch ( $this->date_type )
|
||||
{
|
||||
case 'last_visit':
|
||||
$query->filterByLastUpdatedDate( \IPS\DateTime::ts( \IPS\Member::loggedIn()->last_visit ) );
|
||||
break;
|
||||
case 'relative':
|
||||
$query->filterByLastUpdatedDate( \IPS\DateTime::create()->sub( new \DateInterval( 'P' . intval( $this->date_relative_days ) . 'D' ) ) );
|
||||
case 'custom':
|
||||
$query->filterByLastUpdatedDate( $this->date_start ? \IPS\DateTime::ts( $this->date_start ) : NULL, $this->date_end ? \IPS\DateTime::ts( $this->date_end ) : NULL );
|
||||
break;
|
||||
}
|
||||
|
||||
/* Sort */
|
||||
if ( $this->include_comments )
|
||||
{
|
||||
if ( $this->sort === 'oldest' )
|
||||
{
|
||||
$query->setOrder( \IPS\Content\Search\Query::ORDER_OLDEST_CREATED );
|
||||
}
|
||||
else
|
||||
{
|
||||
$query->setOrder( \IPS\Content\Search\Query::ORDER_NEWEST_CREATED );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( $this->sort === 'oldest' )
|
||||
{
|
||||
$query->setOrder( \IPS\Content\Search\Query::ORDER_OLDEST_UPDATED );
|
||||
}
|
||||
else
|
||||
{
|
||||
$query->setOrder( \IPS\Content\Search\Query::ORDER_NEWEST_UPDATED );
|
||||
}
|
||||
}
|
||||
|
||||
/* Return */
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* URL to this stream
|
||||
*
|
||||
* @return \IPS\Http\Url
|
||||
*/
|
||||
public function url()
|
||||
{
|
||||
if ( $this->id )
|
||||
{
|
||||
switch ( $this->id )
|
||||
{
|
||||
case 1:
|
||||
$furlKey = 'discover_unread';
|
||||
break;
|
||||
case 2:
|
||||
$furlKey = 'discover_istarted';
|
||||
break;
|
||||
case 3:
|
||||
$furlKey = 'discover_followed';
|
||||
break;
|
||||
case 4:
|
||||
$furlKey = 'discover_following';
|
||||
break;
|
||||
case 5:
|
||||
$furlKey = 'discover_posted';
|
||||
break;
|
||||
default:
|
||||
$furlKey = 'discover_stream';
|
||||
break;
|
||||
}
|
||||
return \IPS\Http\Url::internal( "app=core&module=discover&controller=streams&id={$this->id}", 'front', $furlKey );
|
||||
}
|
||||
else
|
||||
{
|
||||
return \IPS\Http\Url::internal( "app=core&module=discover&controller=streams", 'front', 'discover_all' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save Changed Columns
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
parent::save();
|
||||
|
||||
if ( !$this->member )
|
||||
{
|
||||
unset( \IPS\Data\Store::i()->globalStreamIds );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [ActiveRecord] Delete Record
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
if ( $this->member )
|
||||
{
|
||||
parent::delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
parent::delete();
|
||||
unset( \IPS\Data\Store::i()->globalStreamIds );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -86,8 +86,9 @@ class _Reason extends \IPS\Node\Model
|
||||
$form->add( new \IPS\Helpers\Form\Custom( 'wr_remove', $this->id ? array( $this->remove, $this->remove_unit ) : NULL, FALSE, array(
|
||||
'getHtml' => function( $element )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'members' )->warningTime( $element->name, $element->value );
|
||||
return \IPS\Theme::i()->getTemplate( 'members' )->warningTime( $element->name, $element->value, 'after', 'never' );
|
||||
}
|
||||
, 'unlimited' => -1, 'unlimitedLang' => 'never'
|
||||
) ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'wr_remove_override', $this->id ? $this->remove_override : TRUE ) );
|
||||
}
|
||||
@@ -102,8 +103,15 @@ class _Reason extends \IPS\Node\Model
|
||||
{
|
||||
if( isset( $values['wr_remove'] ) )
|
||||
{
|
||||
$values['remove'] = (int) $values['wr_remove'][0];
|
||||
$values['remove_unit'] = $values['wr_remove'][1];
|
||||
if( isset( $values['wr_remove'][3] ) or $values['wr_remove'][0] < 1 )
|
||||
{
|
||||
$values['remove'] = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$values['remove'] = (int) $values['wr_remove'][0];
|
||||
$values['remove_unit'] = $values['wr_remove'][1];
|
||||
}
|
||||
unset( $values['wr_remove'] );
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user