202 lines
5.3 KiB
PHP
202 lines
5.3 KiB
PHP
<?php
|
|
/**
|
|
* @brief Statistics Charts
|
|
* @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 1 Jul 2015
|
|
*/
|
|
|
|
namespace IPS\core\Statistics;
|
|
|
|
/* 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;
|
|
}
|
|
|
|
/**
|
|
* Statistics Charts
|
|
*/
|
|
abstract class _Chart
|
|
{
|
|
/**
|
|
* @brief Controller
|
|
*/
|
|
public $controller = NULL;
|
|
|
|
/**
|
|
* Get Chart
|
|
*
|
|
* @param \IPS\Http\Url $url URL the chart is being shown on.
|
|
*
|
|
* @return \IPS\Helpers\Chart
|
|
*/
|
|
abstract public function getChart( \IPS\Http\Url $url ): \IPS\Helpers\Chart;
|
|
|
|
/**
|
|
* Load from Extension
|
|
*
|
|
* @return static
|
|
* @throws \OutOfRangeException
|
|
*/
|
|
public static function loadFromExtension( string $app, string $extension ): static
|
|
{
|
|
$extensions = \IPS\Application::load( $app )->extensions( 'core', 'Statistics' );
|
|
if ( isset( $extensions[ $extension ] ) )
|
|
{
|
|
return $extensions[ $extension ];
|
|
}
|
|
|
|
throw new \OutOfRangeException;
|
|
}
|
|
|
|
/**
|
|
* Load from Controller
|
|
*
|
|
* @return static
|
|
* @throws \OutOfRangeException
|
|
*/
|
|
public static function loadFromController( string $controller ): static
|
|
{
|
|
foreach( \IPS\Application::allExtensions( 'core', 'Statistics', FALSE ) AS $extension )
|
|
{
|
|
if ( $extension->controller AND $extension->controller === $controller )
|
|
{
|
|
return $extension;
|
|
}
|
|
}
|
|
|
|
throw new \OutOfRangeException;
|
|
}
|
|
|
|
/**
|
|
* Construct a saved chart from data
|
|
*
|
|
* @param array|int $data Chart ID or pre-loaded chart data.
|
|
* @param \IPS\Http\Url $url URL chart is shown on
|
|
* @param \IPS\Member|bool $check Check chart is owned by a specific member, or the currently logged in member if TRUE. If FALSE, no permission checking.
|
|
*
|
|
* @return \IPS\Helpers\Chart
|
|
* @throws \OutOfRangeException
|
|
* @throws \InvalidArgumentException
|
|
*/
|
|
public static function constructMemberChartFromData( array|int $data, \IPS\Http\Url $url, \IPS\Member|bool $check = TRUE ): \IPS\Helpers\Chart
|
|
{
|
|
try
|
|
{
|
|
if ( $check === FALSE )
|
|
{
|
|
if ( !\is_array( $data ) )
|
|
{
|
|
$data = \IPS\Db::i()->select( '*', 'core_saved_charts', array( "id=?", $data ) )->first();
|
|
}
|
|
}
|
|
else if ( ( $check instanceof \IPS\Member ) AND $check->member_id )
|
|
{
|
|
if ( !\is_array( $data ) )
|
|
{
|
|
$data = \IPS\Db::i()->select( '*', 'core_saved_charts', array( "chart_id=? AND chart_member=?", $data, $check->member_id ) )->first();
|
|
}
|
|
else if ( $data['chart_member'] !== $check->member_id )
|
|
{
|
|
throw new \UnderflowException;
|
|
}
|
|
}
|
|
else if ( $check === TRUE AND \IPS\Member::loggedIn()->member_id )
|
|
{
|
|
if ( !\is_array( $data ) )
|
|
{
|
|
$data = \IPS\Db::i()->select( '*','core_saved_charts', array( "chart_id=? AND chart_member=?", $data, \IPS\Member::loggedIn()->member_id ) )->first();
|
|
}
|
|
else if ( $data['chart_member'] !== \IPS\Member::loggedIn()->member_id )
|
|
{
|
|
throw new \UnderflowException;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* If we're here, we were passed a guest object which isn't going to work. Throw a different exception as this should lead directly to a bugfix since this should never happen. */
|
|
throw new \InvalidArgumentException;
|
|
}
|
|
|
|
$extension = static::loadFromController( $data['chart_controller'] );
|
|
$chart = $extension->getChart( $url );
|
|
$currentFilters = array();
|
|
foreach( json_decode( $data['chart_configuration'], true ) AS $k => $v )
|
|
{
|
|
if ( mb_substr( $k, 0, 11 ) == 'customform_' )
|
|
{
|
|
$currentFilters[ mb_substr( $k, 11 ) ] = $v;
|
|
}
|
|
else
|
|
{
|
|
$currentFilters[ $k ] = $v;
|
|
}
|
|
}
|
|
|
|
$chart->savedCustomFilters = $currentFilters;
|
|
$chart->timescale = $data['chart_timescale'] ?? $chart->timescale;
|
|
$chart->title = $data['chart_title'];
|
|
$chart->showFilterTabs = FALSE;
|
|
$chart->showIntervals = FALSE;
|
|
$chart->showDateRange = FALSE;
|
|
|
|
return $chart;
|
|
}
|
|
catch( \UnderflowException $e )
|
|
{
|
|
/* Chart doesn't exist, or isn't owned by $member */
|
|
throw new \OutOfRangeException;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get charts for Member
|
|
*
|
|
* @param \IPS\Http\Url $url URL
|
|
* @param bool $idsOnly Return only ID's belonging to the user for lazyloading.
|
|
* @param \IPS\Member|null $member Member, or NULL for currently logged in member.
|
|
*
|
|
* @return array
|
|
* @throws \InvalidArgumentException
|
|
*/
|
|
public static function getChartsForMember( \IPS\Http\Url $url, bool $idsOnly = FALSE, ?\IPS\Member $member = NULL ): array
|
|
{
|
|
$member ??= \IPS\Member::loggedIn();
|
|
|
|
if ( !$member->member_id )
|
|
{
|
|
throw new \InvalidArgumentException;
|
|
}
|
|
|
|
$return = [];
|
|
|
|
foreach( \IPS\Db::i()->select( '*', 'core_saved_charts', array( "chart_member=?", $member->member_id ) ) AS $chart )
|
|
{
|
|
if ( $idsOnly )
|
|
{
|
|
$return[] = $chart['chart_id'];
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
$controller = explode( '_', $chart['chart_controller'] );
|
|
$return[$chart['chart_id']] = array(
|
|
'chart' => static::constructMemberChartFromData( $chart, $url, $member ),
|
|
'data' => $chart
|
|
);
|
|
}
|
|
catch( \OutOfRangeException )
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $return;
|
|
}
|
|
} |