Version 4.7.23

This commit is contained in:
Neo committed 2025-12-19 16:21:27 -08:00
1 parent 7124a02564
commit 25ddeb65d6
1791 files changed
+76990 -44452

No files matched your search

+14 -2
View File
@@ -61,6 +61,11 @@ class _Database extends \IPS\Helpers\Chart\Dynamic
* @brief Table Column Formatters
*/
public $tableParsers = array();
/**
* @brief Table Lang Prefix
*/
public $tableLangPrefix = NULL;
/**
* @brief Along with the other series, show one of the sum of all
@@ -345,7 +350,7 @@ class _Database extends \IPS\Helpers\Chart\Dynamic
NULL,
NULL,
$this->groupBy
)->setKeyField( $this->groupBy )->setValueField( $key );
);
if( \count( $this->joins ) )
{
@@ -354,7 +359,10 @@ class _Database extends \IPS\Helpers\Chart\Dynamic
$stmt = $stmt->join( $join[0], $join[1], ( isset( $join[2] ) ? $join[2] : 'LEFT' ), ( isset( $join[3] ) ? $join[3] : FALSE ) );
}
}
/* Calling this before the joins are added just executes the query and the joins are never added */
$stmt->setKeyField( $this->groupBy )->setValueField( $key );
foreach ( $stmt as $k => $v )
{
if( \count( $this->availableFilters ) and !\in_array( $k, $this->currentFilters ) )
@@ -581,6 +589,10 @@ class _Database extends \IPS\Helpers\Chart\Dynamic
{
$table->include = $this->tableInclude;
}
if ( $this->tableLangPrefix )
{
$table->langPrefix = $this->tableLangPrefix;
}
$table->parsers = $this->tableParsers;
$table->sortBy = $table->sortBy ?: $this->dateField;
+10 -2
View File
@@ -417,7 +417,7 @@ abstract class _Dynamic extends \IPS\Helpers\Chart
$custom = array();
$chartFilters = ( isset( \IPS\Request::i()->chartFilters ) and \IPS\Request::i()->chartFilters ) ? \IPS\Request::i()->chartFilters : array();
$this->timescale = $chart['chart_timescale'] ?? 'monthly';
$this->timescale = ( isset( \IPS\Request::i()->timescale ) and \IPS\Request::i()->timescale[ $this->identifier ] ) ? \IPS\Request::i()->timescale[ $this->identifier ] : $chart['chart_timescale'] ?? 'monthly';
foreach( \IPS\Request::i() as $key => $value )
{
@@ -779,7 +779,15 @@ abstract class _Dynamic extends \IPS\Helpers\Chart
/* Anything else can just save as-is */
default:
$save[] = $row[$i];
if ( \is_array( $row[$i] ) )
{
/* GeoCharts use arrays so we need to use the value rather */
$save[] = $row[$i]['value'];
}
else
{
$save[] = $row[$i];
}
break;
}
$i++;
+103
View File
@@ -0,0 +1,103 @@
<?php
/**
* @brief Cloudflare Turnstile
* @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 13 June 2025
*/
namespace IPS\Helpers\Form\Captcha;
use IPS\Http\Request\Exception;
use IPS\Http\Url;
use IPS\Log;
use IPS\Member;
use IPS\Request;
use IPS\Settings;
use IPS\Theme;
use RuntimeException;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Cloudflare Turnstile
*/
class _Turnstile implements CaptchaInterface
{
/**
* Does this CAPTCHA service support being added in a modal?
*/
public static bool $supportsModal = TRUE;
/**
* @brief Error
*/
protected ?string $error;
/**
* Display
*
* @return string
*/
public function getHtml(): string
{
return Theme::i()->getTemplate( 'forms', 'core', 'global' )->captchaTurnstile( $this->getTurnstileCredentials()['site_key'], preg_replace( '/^(.+?)\..*$/', '$1', Member::loggedIn()->language()->short ) );
}
/**
* Verify
*
* @return bool|null TRUE/FALSE indicate if the test passed or not. NULL indicates the test failed, but the captcha system will display an error so we don't have to.
*/
public function verify(): ?bool
{
try
{
$response = Url::external( 'https://challenges.cloudflare.com/turnstile/v0/siteverify' )->request(5)->post( [
'secret' => $this->getTurnstileCredentials()['secret_key'],
'response' => trim( Request::i()->__get('cf-turnstile-response') ),
'remoteip' => Request::i()->ipAddress(),
] )->decodeJson();
return ( ( $response['success'] ) and ( $response['hostname'] === Url::internal('')->data[ Url::COMPONENT_HOST ] ) );
}
catch( Exception $e )
{
Log::log( $e, 'turnstile_exception' );
return FALSE;
}
catch( RuntimeException $e )
{
if( $e->getMessage() == 'BAD_JSON' )
{
return FALSE;
}
else
{
throw $e;
}
}
}
/**
* Get Turnstile credentials
*
* @return array
*/
public function getTurnstileCredentials(): array
{
return [
'site_key' => Settings::i()->turnstile_site_key,
'secret_key' => Settings::i()->turnstile_secret_key
];
}
}
+5 -1
View File
@@ -35,8 +35,9 @@ class _Editor extends FormAbstract
'foo'
),
'attachIdsLang' => NULL, // Language ID number if this Editor is part of a Translatable field.
'minimize' => 'clickme', // Language string to use for minimized view. NULL will mean editor is not minimized.
'minimize' => 'clickme', // Language string to use for minimized view. NULL will mean editor is not minimized.0
'minimizeIcon' => 'flag-us', // Icon to use for minimized view
'minimizeAfterReset' => FALSE, // Whether to minimize the editor after resetting (note resetting is handled by JS usually after AJAX submission)
'allButtons' => FALSE, // Only used for the customisation ACP page. Do not use.
'tags' => array(), // An array of extra insertable tags in key => value pair with key being what is inserted and value serving as a description
'autoGrow' => FALSE, // Used to specify if editor should grow in size as content is added. Defaults to TRUE.
@@ -59,6 +60,7 @@ class _Editor extends FormAbstract
'attachIdsLang' => NULL,
'minimize' => NULL,
'minimizeIcon' => 'fa fa-comment-o',
'minimizeAfterReset' => FALSE,
'allButtons' => FALSE,
'tags' => array(),
'autoGrow' => TRUE,
@@ -524,6 +526,7 @@ class _Editor extends FormAbstract
}
/* Remove abandoned attachments */
/* @note SELECT_FROM_WRITE_SERVER Added in d901b5446e4fca3fc88c55d2de19397aeafc8911 We need to fetch from the write server to make sure we have all recenty added attachments */
foreach ( \IPS\Db::i()->select( '*', 'core_attachments', array( array( 'attach_id NOT IN(?)', \IPS\Db::i()->select( 'DISTINCT attachment_id', 'core_attachments_map', NULL, NULL, NULL, NULL, NULL, \IPS\Db::SELECT_FROM_WRITE_SERVER ) ), array( 'attach_member_id=? AND attach_date<?', \IPS\Member::loggedIn()->member_id, time() - 86400 ) ) ) as $attachment )
{
try
@@ -723,6 +726,7 @@ class _Editor extends FormAbstract
{
try
{
/* @note SELECT_FROM_WRITE_SERVER added 735824c35ab73cd81bd31cdfcc0435a71104f942 "RW DB issue with inserting data into core_temp_files and then reading it back" */
$fileInfo = \IPS\Db::i()->select( 'requires_moderation, labels', 'core_files_temp', array( 'contents=?', (string) $file ), NULL, NULL, NULL, NULL, \IPS\Db::SELECT_FROM_WRITE_SERVER )->first();
$requiresModeration = (bool) $fileInfo['requires_moderation'];
$labels = $fileInfo['labels'];
+4
View File
@@ -469,6 +469,10 @@ class _Node extends FormAbstract
{
return NULL;
}
else if ( $this->options['clubs'] AND $this->options['permissionCheck'] == 'add' )
{
return 'add';
}
else
{
return ( \IPS\Dispatcher::hasInstance() and \IPS\Dispatcher::i()->controllerLocation === 'front' ) ? 'view' : NULL;
+1 -1
View File
@@ -321,7 +321,7 @@ class _Upload extends FormAbstract
}
catch ( \Exception $e )
{
\IPS\Log::log( $e, 'upload_failure' );
\IPS\Log::debug( $e, 'upload_failure' );
$message = $e->getMessage();
@@ -149,7 +149,7 @@ class _MultipleRedirect
public function __toString()
{
/* Don't cache for a short while to ensure sessions work */
\IPS\Output::i()->pageCaching = FALSE;
\IPS\Output::setCacheTime( false );
return $this->output ?: \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->multipleRedirect( $this->url, ( ( isset( \IPS\Request::i()->mr_continue ) and isset( \IPS\Request::i()->mr ) ) ? \IPS\Request::i()->mr : 0 ), isset( \IPS\Request::i()->_wizardHeight ) ? \intval( \IPS\Request::i()->_wizardHeight ) : NULL );
}
+14 -4
View File
@@ -94,6 +94,7 @@ class _Db extends Table
/**
* Get rows
* @note This method is called twice, so if there'some expensive operation happening, or if you're calculating something, make sure to cache it.
*
* @param array $advancedSearchValues Values from the advanced search form
* @return array
@@ -107,7 +108,7 @@ class _Db extends Table
{
$where[] = \is_array( $this->filters[ $this->filter ] ) ? $this->filters[ $this->filter ] : array( $this->filters[ $this->filter ] );
}
/* Add quick search term to where clause if necessary */
if ( $this->quickSearch !== NULL and \IPS\Request::i()->quicksearch )
{
@@ -303,6 +304,7 @@ class _Db extends Table
}
$selects = $this->selects;
$isOtherJoin = false;
if ( \count( $this->joins ) )
{
@@ -312,12 +314,20 @@ class _Db extends Table
{
$selects[] = $join['select'];
}
if ( isset( $join['type'] ) and \mb_strtolower( $join['type'] ) != 'left' )
{
/* Inner join or straight join which will affect the query results */
$isOtherJoin = true;
}
}
}
/* Count results (for pagination) */
$count = $this->db->select( 'count(*)', $this->table, $where, NULL, NULL, $this->groupBy );
if ( \count( $this->joins ) )
/* Add the joins if we have a where statement and all joins are left for the count */
if ( ( $isOtherJoin or \count( $where ) ) and \count( $this->joins ) )
{
foreach( $this->joins as $join )
{
@@ -366,7 +376,7 @@ class _Db extends Table
}
else
{
list( $field, $direction ) = explode( ' ', $v );
[ $field, $direction ] = explode( ' ', $v );
$return = ( isset( $this->advancedSearch[$v] ) and $this->advancedSearch[$v] == SEARCH_NUMERIC_TEXT ) ? 'LENGTH(' . '`' . trim( $field ) . '`' . ') ' . mb_strtolower( $direction ) == 'asc' ? 'asc' : 'desc' . ', ' . '`' . trim( $field ) . '` ' : '`' . trim( $field ) . '` ';
$return .= ( mb_strtolower( $direction ) == 'asc' ? 'asc' : 'desc' );
}
@@ -538,7 +548,7 @@ class _Db extends Table
if ( mb_strstr( $field, ' ' ) )
{
list( $field, $direction ) = explode( ' ', $field );
[ $field, $direction ] = explode( ' ', $field );
}
if ( !array_key_exists( trim($field), $count ) )
+1 -1
View File
@@ -120,7 +120,7 @@ class _Wizard
public function __toString()
{
/* Don't cache for a short while to ensure sessions work */
\IPS\Output::i()->pageCaching = FALSE;
\IPS\Output::setCacheTime( false );
try
{