Version 4.7.6

This commit is contained in:
Neo committed 2025-12-19 16:05:19 -08:00
1 parent 8ba7d43898
commit 7b7404e741
1085 files changed
+30590 -7837

No files matched your search

+61
View File
@@ -0,0 +1,61 @@
<?php
/**
* @brief Base API Graph Controller
* @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 Sept 2022
*/
namespace IPS\Api;
/* 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;
}
/**
* Base API Controller
*/
class _GraphQL
{
public function __construct()
{
/* This space intentionally left blank */
}
/**
* Execute
*
* @param string $query The query to execute
* @param array $variables Variables to include in query
* @return array GraphQL response
*/
public static function execute( string $query, array $variables = [], array $member = NULL )
{
/* Register our GraphQL library */
\IPS\IPS::$PSR0Namespaces['GraphQL'] = \IPS\ROOT_PATH . "/system/3rd_party/graphql-php";
/* Execute! */
$result = \GraphQL\GraphQL::executeQuery(
new \GraphQL\Type\Schema([
'query' => \IPS\Api\GraphQL\TypeRegistry::query(),
'mutation' => \IPS\Api\GraphQL\TypeRegistry::mutation()
]),
$query,
NULL, // $rootValue
[
'member' => \IPS\Member::loggedIn()
], // $context
$variables
);
/* Convert result into JSON and send */
$output = $result->toArray( ( \IPS\IN_DEV OR \IPS\DEBUG_GRAPHQL ) ? \GraphQL\Error\DebugFlag::INCLUDE_DEBUG_MESSAGE | \GraphQL\Error\DebugFlag::INCLUDE_TRACE : false );
return $output;
}
}
+12 -6
View File
@@ -64,7 +64,7 @@ class _PaginatedResponse extends Response
* @param \Iterator $iterator Select query or \IPS\Patterns\ActiveRecordIterator instance
* @param int $page Current page
* @param string $activeRecordClass ActiveRecord class
* @param int $count Total Count
* @param int|NULL $count Total Count
* @param \IPS\Member|NULL $authorizedMember The member making the API request or NULL for API Key / client_credentials
* @param int $perPage Number of results per page
* @return void
@@ -78,6 +78,17 @@ class _PaginatedResponse extends Response
$this->count = (int) $count;
$this->resultsPerPage = $perPage ? (int) $perPage : 25;
$this->authorizedMember = $authorizedMember;
if( $this->iterator instanceof \IPS\Db\Select )
{
/* Limit the query before calling count(), as this runs the query so it cannot be modified after */
$this->iterator->query .= \IPS\Db::i()->compileLimitClause( array( ( $this->page - 1 ) * $this->resultsPerPage, $this->resultsPerPage ) );
if ( $count === NULL )
{
$this->count = $iterator->count();
}
}
}
/**
@@ -89,11 +100,6 @@ class _PaginatedResponse extends Response
{
$results = array();
if( $this->iterator instanceof \IPS\Db\Select )
{
$this->iterator->query .= \IPS\Db::i()->compileLimitClause( array( ( $this->page - 1 ) * $this->resultsPerPage, $this->resultsPerPage ) );
}
if ( $this->activeRecordClass )
{
if( $this->iterator instanceof \IPS\Patterns\ActiveRecordIterator )
+29 -2
View File
@@ -77,6 +77,7 @@ class _Webhook extends \IPS\Node\Model
*/
public function setDefaultValues()
{
$this->content_type = 'application/x-www-form-urlencoded';
$this->_data['filters'] = '{}';
$this->_data['url'] = '';
$this->_data['events'] = '';
@@ -91,6 +92,19 @@ class _Webhook extends \IPS\Node\Model
public function form( &$form )
{
$form->add( new \IPS\Helpers\Form\Url( 'url', $this->url ?? "", TRUE ) );
if( \in_array($this->content_type, ['application/x-www-form-urlencoded', 'application/json']))
{
$selectedHeader = $this->content_type;
$customHeader = '';
}
else
{
$selectedHeader = 'custom';
$customHeader = $this->content_type;
}
$form->add( new \IPS\Helpers\Form\Select('webhook_content_type', $selectedHeader, TRUE , ['options' => ['application/x-www-form-urlencoded' => 'x-www-form-urlencoded', 'application/json' => 'application/json', 'custom' => 'Other'] , 'toggles'=> ['custom' => ['webhook_content_type_other'] ] ] ) );
$form->add( new \IPS\Helpers\Form\Text('webhook_content_type_other', $customHeader, FALSE , [], NULL, NULL, NULL, 'webhook_content_type_other' ) );
$events = [];
foreach ( \IPS\Api\Webhook::getAvailableWebhooks() as $app => $hooks )
@@ -116,8 +130,17 @@ class _Webhook extends \IPS\Node\Model
public function formatFormValues( $values )
{
$values['events'] = $values['webhook_events'];
unset( $values['webhook_events'] );
if( $values['webhook_content_type'] AND $values['webhook_content_type'] === 'custom' )
{
$values['content_type'] = $values['webhook_content_type_other'];
}
else
{
$values['content_type'] = $values['webhook_content_type'];
}
unset( $values['webhook_events'], $values['webhook_content_type'], $values['webhook_content_type_other'] );
return $values;
}
@@ -147,6 +170,9 @@ class _Webhook extends \IPS\Node\Model
*/
public static function fire( $event, $data = NULL, $filters = array() )
{
/* This will intentionally not call $data::apiOutput to avoid unnecessary overhead here */
\IPS\Log::debug( print_r( array_merge(['event' => $event], ['payload' => $data], ['filters' => $filters ]) , TRUE ), 'webhook_fire_call');
/* Get our webhooks from cache */
if ( !isset( \IPS\Data\Store::i()->webhooks ) )
{
@@ -163,7 +189,8 @@ class _Webhook extends \IPS\Node\Model
$webhooks[ $e ][ $row['id'] ] = array(
'key' => $row['api_key'],
'url' => $row['url'],
'filters' => json_decode( $row['filters'], TRUE )
'filters' => json_decode( $row['filters'], TRUE ),
'content_type_header' => $row['content_type']
);
}
}