Version 5.0.0 beta 5
This commit is contained in:
1 parent
2f24f9de48
commit
57d9db6ce2
218 files changed
+5331
-7416
No files matched your search
+21
-10
@@ -13,8 +13,10 @@ namespace IPS\Api;
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
|
||||
use DirectoryIterator;
|
||||
use ErrorException;
|
||||
use IPS\Application;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Log;
|
||||
use IPS\Member;
|
||||
use IPS\Output;
|
||||
use IPS\Settings;
|
||||
@@ -281,22 +283,31 @@ abstract class Controller
|
||||
{
|
||||
$controllerName = mb_substr( $file, 0, -4 );
|
||||
$class = 'IPS\\' . $app->directory . '\\api\\' . $controllerName;
|
||||
if( class_exists( $class ) )
|
||||
{
|
||||
$reflection = new ReflectionClass( $class );
|
||||
foreach ( $reflection->getMethods() as $method )
|
||||
{
|
||||
if ( $method->getName() != 'execute' and !$method->isStatic() and $method->isPublic() and mb_substr( $method->getName(), 0, 1 ) != '_' )
|
||||
{
|
||||
$details = static::decodeDocblock( $method->getDocComment() );
|
||||
|
||||
if ( ( $type !== 'client' or !isset( $details['details']['apimemberonly'] ) ) and ( $type !== 'member' or !isset( $details['details']['apiclientonly'] ) ) )
|
||||
try
|
||||
{
|
||||
if( class_exists( $class ) )
|
||||
{
|
||||
$reflection = new ReflectionClass( $class );
|
||||
foreach ( $reflection->getMethods() as $method )
|
||||
{
|
||||
if ( $method->getName() != 'execute' and !$method->isStatic() and $method->isPublic() and mb_substr( $method->getName(), 0, 1 ) != '_' )
|
||||
{
|
||||
$return[ $app->directory . '/' . $controllerName . '/' . $method->getName() ] = $details;
|
||||
$details = static::decodeDocblock( $method->getDocComment() );
|
||||
|
||||
if ( ( $type !== 'client' or !isset( $details['details']['apimemberonly'] ) ) and ( $type !== 'member' or !isset( $details['details']['apiclientonly'] ) ) )
|
||||
{
|
||||
$return[ $app->directory . '/' . $controllerName . '/' . $method->getName() ] = $details;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( ErrorException $e )
|
||||
{
|
||||
/* This can happen if we have legacy files floating around */
|
||||
Log::debug( "BAD_API_CLASS", 'api' );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -347,6 +347,9 @@ trait Assignable
|
||||
*/
|
||||
public static function assignmentFormField( Item $item, ?Model $container=null, ?string $fieldName=null ) : FormAbstract
|
||||
{
|
||||
/* Preload some language strings */
|
||||
Member::loggedIn()->language()->get( ['assignment_team', 'assign_to'] );
|
||||
|
||||
$prefix = Member::loggedIn()->language()->get( 'assignment_team' );
|
||||
$currentValue = null;
|
||||
if( $currentAssignment = $item->assignment )
|
||||
|
||||
+10
-4
@@ -2833,12 +2833,15 @@ abstract class Item extends Content
|
||||
/* Work out the order */
|
||||
if ( $order === NULL )
|
||||
{
|
||||
$dateColumn = static::$databaseColumnMap['date'];
|
||||
if ( is_array( $dateColumn ) )
|
||||
if( isset( static::$databaseColumnMap[ 'date' ] ) )
|
||||
{
|
||||
$dateColumn = array_pop( $dateColumn );
|
||||
$dateColumn = static::$databaseColumnMap['date'];
|
||||
if ( is_array( $dateColumn ) )
|
||||
{
|
||||
$dateColumn = array_pop( $dateColumn );
|
||||
}
|
||||
$order = static::$databaseTable . '.' . static::$databasePrefix . $dateColumn . ' DESC';
|
||||
}
|
||||
$order = static::$databaseTable . '.' . static::$databasePrefix . $dateColumn . ' DESC';
|
||||
}
|
||||
|
||||
$containerWhere = array();
|
||||
@@ -6340,6 +6343,9 @@ abstract class Item extends Content
|
||||
{
|
||||
$blurb = NULL;
|
||||
|
||||
/* Preload some language strings */
|
||||
Member::loggedIn()->language()->get( ['comment_meta_date_weeks_later', 'comment_meta_date_months_later', 'comment_meta_date_years_later'] );
|
||||
|
||||
/* Years? */
|
||||
if ( $nextDate->diff( $date )->y > 0 )
|
||||
{
|
||||
|
||||
@@ -575,8 +575,9 @@ trait Reactable
|
||||
$this->hasReacted[ $member->member_id ] = Content\Reaction::load( $this->reputation[ $member->member_id ] );
|
||||
}
|
||||
}
|
||||
else
|
||||
elseif ( ! is_array( $this->reputation ) )
|
||||
{
|
||||
/* $this->reputation is not set, so we need to query the database */
|
||||
$where = $this->getReactionWhereClause( NULL, FALSE );
|
||||
$where[] = array( 'member_id=?', $member->member_id );
|
||||
$this->hasReacted[ $member->member_id ] = Content\Reaction::load( Db::i()->select( 'reaction', 'core_reputation_index', $where )->first() );
|
||||
|
||||
@@ -397,16 +397,7 @@ trait Statistics
|
||||
return array();
|
||||
}
|
||||
|
||||
$return = array();
|
||||
foreach( new ActiveRecordIterator( Db::i()->select( '*', $commentClass::$databaseTable, array( Db::i()->in( $commentIdField, $postIds ) ), "FIND_IN_SET( {$commentIdField}, '" . implode( ",", $postIds ) . "' )", array( 0, $count ) ), $commentClass ) as $comment )
|
||||
{
|
||||
if ( $comment->canView() and $comment->mapped('item') == $this->$idField and isset( $counts[ $comment->$commentIdField ] ) )
|
||||
{
|
||||
$return[] = array( 'comment' => $comment, 'count' => $counts[ $comment->$commentIdField ] );
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
return $this->getComments( $commentClass, $commentIdField, $idField, $postIds, $count, $counts );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -469,18 +460,40 @@ trait Statistics
|
||||
return array();
|
||||
}
|
||||
|
||||
$return = array();
|
||||
foreach( new ActiveRecordIterator( Db::i()->select( '*', $commentClass::$databaseTable, array( Db::i()->in( $commentIdField, $postIds ) ), "FIND_IN_SET( {$commentIdField}, '" . implode( ",", $postIds ) . "' )", array( 0, $count ) ), $commentClass ) as $comment )
|
||||
return $this->getComments( $commentClass, $commentIdField, $idField, $postIds, $count, $counts );
|
||||
}
|
||||
|
||||
protected $commentCache = array();
|
||||
|
||||
/**
|
||||
* Get the comments, storing them for later use in the same request
|
||||
*
|
||||
* @param string $commentClass
|
||||
* @param string $commentIdField
|
||||
* @param string $idField
|
||||
* @param array $postIds
|
||||
* @param int $count
|
||||
* @param array $counts
|
||||
* @return array
|
||||
*/
|
||||
protected function getComments( string $commentClass, string $commentIdField, string $idField, array $postIds, int $count, array $counts ): array
|
||||
{
|
||||
$key = md5( $commentClass . $commentIdField . $idField . implode( ',', $postIds ) . $count . json_encode( $counts ) );
|
||||
|
||||
if ( ! isset( $this->commentCache[ $key ] ) )
|
||||
{
|
||||
if ( $comment->canView() and $comment->mapped('item') == $this->$idField and isset( $counts[ $comment->$commentIdField ] ) )
|
||||
$this->commentCache[ $key ] = [];
|
||||
foreach ( new ActiveRecordIterator( Db::i()->select( '*', $commentClass::$databaseTable, [Db::i()->in( $commentIdField, $postIds )], "FIND_IN_SET( {$commentIdField}, '" . implode( ",", $postIds ) . "' )", [0, $count] ), $commentClass ) as $comment )
|
||||
{
|
||||
$return[] = array( 'comment' => $comment, 'count' => $counts[ $comment->$commentIdField ] );
|
||||
if ( $comment->canView() and $comment->mapped( 'item' ) == $this->$idField and isset( $counts[$comment->$commentIdField] ) )
|
||||
{
|
||||
$this->commentCache[ $key ][] = ['comment' => $comment, 'count' => $counts[$comment->$commentIdField]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
return $this->commentCache[ $key ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the top 10 popular days for posts
|
||||
*
|
||||
|
||||
@@ -146,11 +146,11 @@ class Front extends Standard
|
||||
static::baseJs();
|
||||
|
||||
/* Get the current page, if any */
|
||||
if ( isset( Request::i()->page ) )
|
||||
if ( isset( Request::i()->page ) and is_numeric( Request::i()->page ) )
|
||||
{
|
||||
$this->currentPage = Request::i()->page;
|
||||
}
|
||||
else if ( isset( Request::i()->url()->hiddenQueryString['page'] ) and $page = Request::i()->url()->hiddenQueryString['page'] )
|
||||
else if ( isset( Request::i()->url()->hiddenQueryString['page'] ) and is_numeric( Request::i()->url()->hiddenQueryString['page'] ) and $page = Request::i()->url()->hiddenQueryString['page'] )
|
||||
{
|
||||
$this->currentPage = $page;
|
||||
}
|
||||
|
||||
@@ -103,7 +103,10 @@ class Event
|
||||
static::$_listeners = [];
|
||||
foreach( $allListeners[ $class ] as $listener )
|
||||
{
|
||||
static::$_listeners[ $class ][] = new $listener;
|
||||
if( class_exists( $listener ) )
|
||||
{
|
||||
static::$_listeners[ $class ][] = new $listener;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,7 +118,10 @@ class Event
|
||||
{
|
||||
foreach( $listners as $listener )
|
||||
{
|
||||
static::$_listeners[ $class ][] = new $listener;
|
||||
if( class_exists( $listener ) )
|
||||
{
|
||||
static::$_listeners[ $class ][] = new $listener;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ namespace IPS\Extensions;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
use IPS\core\Approval;
|
||||
use RuntimeException;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
@@ -33,9 +32,11 @@ abstract class ApprovalReasonAbstract
|
||||
|
||||
/**
|
||||
* Parse Reason
|
||||
* Return an array with 2 elements: lang (the language string to use)
|
||||
* and sprintf (an array of replacements)
|
||||
*
|
||||
* @param Approval $approval Approval row
|
||||
* @return array<lang,sprintf>
|
||||
* @return array
|
||||
*/
|
||||
abstract public function parseReason( Approval $approval ): array;
|
||||
}
|
||||
@@ -15,7 +15,6 @@ namespace IPS\Extensions;
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
use IPS\Member\Club;
|
||||
use IPS\Node\Model;
|
||||
use RuntimeException;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
@@ -28,8 +27,8 @@ abstract class ClubAbstract
|
||||
/**
|
||||
* Tabs
|
||||
*
|
||||
* @param \IPS\Member\Club $club The club
|
||||
* @param \IPS\Node\Model $container Container
|
||||
* @param Club $club The club
|
||||
* @param Model|null $container Container
|
||||
* @return array
|
||||
*/
|
||||
abstract public function tabs( Club $club, ?Model $container = NULL ): array;
|
||||
|
||||
@@ -561,7 +561,7 @@ abstract class Dynamic extends Chart
|
||||
|
||||
if( !Request::i()->isAjax() OR ( Request::i()->tab AND !Request::i()->chartId ) )
|
||||
{
|
||||
return Theme::i()->getTemplate( 'global', 'core' )->tabs( $this->getChartTabs(), ( isset( Request::i()->chartId ) ) ? Request::i()->chartId : NULL, $chartOutput, $this->url, 'chartId', 'ipsTabs_small ipsTabs_contained' );
|
||||
return Theme::i()->getTemplate( 'global', 'core' )->tabs( $this->getChartTabs(), ( isset( Request::i()->chartId ) ) ? Request::i()->chartId : NULL, $chartOutput, $this->url, 'chartId', 'ipsTabs--small' );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -457,13 +457,14 @@ class Upload extends FormAbstract
|
||||
/* Set existing files */
|
||||
if ( $this->options['temporary'] )
|
||||
{
|
||||
$fileSize = mb_strlen( file_get_contents( $file ) );
|
||||
$existing[] = array(
|
||||
'id' => $id,
|
||||
'insertable' => (bool) $this->options['postKey'],
|
||||
'hasThumb' => false,
|
||||
'originalFileName' => $file,
|
||||
'size' => Filesize::humanReadableFilesize( $file, FALSE, TRUE ),
|
||||
'sizeRaw' => $file,
|
||||
'size' => Filesize::humanReadableFilesize( $fileSize, FALSE, TRUE ),
|
||||
'sizeRaw' => $fileSize,
|
||||
'custom' => NULL
|
||||
);
|
||||
}
|
||||
|
||||
+1
-1
@@ -862,7 +862,7 @@ class Url
|
||||
}
|
||||
|
||||
/* Set a default user-agent (some services, e.g. spotify, block requests without one but it's good to do so anyway) */
|
||||
$requestObj->setHeaders( array( 'User-Agent' => 'Invision Community 4' ) );
|
||||
$requestObj->setHeaders( array( 'User-Agent' => 'Invision Community 5' ) );
|
||||
|
||||
/* Return */
|
||||
return $requestObj;
|
||||
|
||||
@@ -145,8 +145,8 @@ class Friendly extends Internal
|
||||
{
|
||||
[ $pagePath, $pageNumber ] = Page::getStrippedPagePath( $potentialFurl );
|
||||
|
||||
/* Is this from the static folders? */
|
||||
if ( mb_substr( $pagePath, 0, 7 ) === 'static/' )
|
||||
/* Is this from the static folders or upload folders? */
|
||||
if ( mb_substr( $pagePath, 0, 7 ) === 'static/' or mb_substr( $pagePath, 0, 8 ) === 'uploads/' )
|
||||
{
|
||||
/* Yes, so just return to avoid looking it up in pages when it won't be there */
|
||||
return $return;
|
||||
|
||||
@@ -2126,7 +2126,7 @@ class Member extends ActiveRecord
|
||||
*/
|
||||
public function isFollowing( array $memberIds ): array
|
||||
{
|
||||
$memberIds = array_filter( $memberIds );
|
||||
$memberIds = array_unique( array_filter( $memberIds ) );
|
||||
if ( !$memberIds )
|
||||
{
|
||||
return array();
|
||||
@@ -3431,6 +3431,12 @@ class Member extends ActiveRecord
|
||||
}
|
||||
|
||||
$perms = $this->modPermissions();
|
||||
|
||||
if ( $perms === false )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ( Content::routedClasses( $this, FALSE, TRUE ) as $_class )
|
||||
{
|
||||
if( isset( $perms[ "can_view_reports_{$_class::$title}" ] ) and $perms[ "can_view_reports_{$_class::$title}" ] )
|
||||
|
||||
@@ -67,7 +67,7 @@ class UserMenu
|
||||
|
||||
foreach( Application::allExtensions( 'core', 'UserMenu', $member ) as $ext )
|
||||
{
|
||||
foreach( $ext->accountMenu( 'content' ) as $element )
|
||||
foreach( $ext->accountMenu( 'settings' ) as $element )
|
||||
{
|
||||
$menu->add( $element );
|
||||
}
|
||||
@@ -102,7 +102,7 @@ class UserMenu
|
||||
|
||||
foreach( Application::allExtensions( 'core', 'UserMenu', $member ) as $ext )
|
||||
{
|
||||
foreach( $ext->accountMenu( 'settings' ) as $element )
|
||||
foreach( $ext->accountMenu( 'content' ) as $element )
|
||||
{
|
||||
$menu->add( $element );
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace IPS\Output;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
|
||||
use IPS\Db;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Output;
|
||||
@@ -176,6 +177,9 @@ class System extends Output
|
||||
cursor: pointer;
|
||||
color: blue;
|
||||
}
|
||||
tr.explain-table {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
function toggleRow(id) {
|
||||
@@ -214,6 +218,36 @@ HTML;
|
||||
foreach ($debug as $index => $data)
|
||||
{
|
||||
$unique = md5( $data['query'] . uniqid() );
|
||||
$explain = null;
|
||||
$explainHtml = '';
|
||||
|
||||
/* If this is a select query, we can get the explain */
|
||||
if ( stripos( $data['query'], 'SELECT' ) !== false )
|
||||
{
|
||||
if( $result = Db::i()->query( "EXPLAIN " . $data['query'] ) )
|
||||
{
|
||||
$explain = $result->fetch_assoc();
|
||||
}
|
||||
}
|
||||
|
||||
if ( $explain )
|
||||
{
|
||||
$explainHtml = '<table class="explain"><tr>';
|
||||
foreach( array_keys( $explain ) as $header )
|
||||
{
|
||||
$explainHtml .= "<th>{$header}</th>";
|
||||
}
|
||||
$explainHtml .= '</tr><tr>';
|
||||
|
||||
foreach( $explain as $key => $value )
|
||||
{
|
||||
$explainHtml .= "<td>{$value}</td>";
|
||||
}
|
||||
|
||||
$explainHtml .= '</tr></table>';
|
||||
}
|
||||
|
||||
|
||||
$html .= <<<HTML
|
||||
<tr>
|
||||
<td data-query="{$unique}" colspan="3" class="query">{$data['query']}</td>
|
||||
@@ -227,21 +261,28 @@ HTML;
|
||||
$trace['line'] = $trace['line'] ?? '';
|
||||
$html .= <<<HTML
|
||||
<tr data-row="content-{$unique}" style="display: none" class="collapsible-content">
|
||||
<td>
|
||||
{$trace['function']}
|
||||
</td>
|
||||
<td>
|
||||
{$trace['file']}
|
||||
</td>
|
||||
<td>
|
||||
{$trace['line']}
|
||||
</td>
|
||||
<td>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<td>
|
||||
{$trace['function']}
|
||||
</td>
|
||||
<td>
|
||||
{$trace['file']}
|
||||
</td>
|
||||
<td>
|
||||
{$trace['line']}
|
||||
</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
HTML;
|
||||
}
|
||||
|
||||
$html .= <<<HTML
|
||||
<tr data-row="content-{$unique}" style="display: none" class="collapsible-content explain-table">
|
||||
<td colspan="4">
|
||||
{$explainHtml}
|
||||
</td>
|
||||
</tr>
|
||||
HTML;
|
||||
|
||||
}
|
||||
|
||||
$html .= <<<HTML
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief A HTMLPurifier Attribute Definition used for attributes which must be internal URLs or Integers (such as data-fileid for attachments)
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) Invision Power Services, Inc.
|
||||
* @license https://www.invisioncommunity.com/legal/standards/
|
||||
* @package Invision Community
|
||||
* @since 21 October 2024
|
||||
*/
|
||||
|
||||
namespace IPS\Text;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* A HTMLPurifier Attribute Definition used for attributes which must be internal URLs or Integers (such as data-fileid for attachments)
|
||||
*/
|
||||
class HtmlPurifierIntOrInternalLink extends HtmlPurifierInternalLinkDef
|
||||
{
|
||||
/**
|
||||
* Validate
|
||||
*
|
||||
* @param string $value
|
||||
* @param \HTMLPurifier_Config $config
|
||||
* @param \HTMLPurifier_Context $context
|
||||
* @return bool|string
|
||||
*/
|
||||
public function validate( $value, $config, $context ): bool|string
|
||||
{
|
||||
$parentCheck = parent::validate( $value, $config, $context );
|
||||
|
||||
if( $parentCheck !== FALSE )
|
||||
{
|
||||
return $parentCheck;
|
||||
}
|
||||
|
||||
$integer = new \HTMLPurifier_AttrDef_Integer( false );
|
||||
return $integer->validate( $value, $config, $context );
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ use HTMLPurifier_Config;
|
||||
use HTMLPurifier_Context;
|
||||
use IPS\File;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Http\Url\Exception as UrlException;
|
||||
use IPS\Http\Url\Friendly;
|
||||
use IPS\Http\Url\Internal;
|
||||
use IPS\Settings;
|
||||
@@ -61,8 +62,15 @@ class HtmlPurifierInternalLinkDef extends HTMLPurifier_AttrDef_URI
|
||||
public function validate($uri, $config, $context): bool|string
|
||||
{
|
||||
/* Create the URL */
|
||||
$url = Url::createFromString( str_replace( array( '%7B___base_url___%7D/', '{___base_url___}/' ), Settings::i()->base_url, $uri ) );
|
||||
|
||||
try
|
||||
{
|
||||
$url = Url::createFromString( str_replace( array( '%7B___base_url___%7D/', '{___base_url___}/' ), Settings::i()->base_url, $uri ) );
|
||||
}
|
||||
catch( UrlException $e )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* If it's not internal, we can stop now */
|
||||
if ( !( $url instanceof Internal ) )
|
||||
{
|
||||
|
||||
@@ -608,8 +608,8 @@ class Parser
|
||||
$def->addAttribute( 'img', 'data-emoticon', 'Bool' ); // Identifies emoticons and stops lightbox running on them
|
||||
|
||||
/* Attachments (set by _parseAElement, _parseImgElement and "insert existing attachment") - Gallery/Downloads use the full URL rather than an ID, hence Text */
|
||||
$def->addAttribute( 'a', 'data-fileid', 'Text' );
|
||||
$def->addAttribute( 'img', 'data-fileid', 'Text' );
|
||||
$def->addAttribute( 'a', 'data-fileid', new HtmlPurifierIntOrInternalLink() );
|
||||
$def->addAttribute( 'img', 'data-fileid', new HtmlPurifierIntOrInternalLink() );
|
||||
$def->addAttribute( 'a', 'data-fileext', 'Text' );
|
||||
|
||||
/* Existing media (inserted with data-extension by the JS so that _getFile is able to locate) */
|
||||
@@ -632,7 +632,7 @@ class Parser
|
||||
/* iFrames (used by embeddableMedia) */
|
||||
$def->addAttribute( 'iframe', 'data-controller', new HTMLPurifier_AttrDef_Enum( array( 'core.front.core.autosizeiframe' ) ) ); // used in core/global/embed/iframe.phtml
|
||||
$def->addAttribute( 'iframe', 'data-embedid', 'Text' ); // used in core/global/embed/iframe.phtml
|
||||
$def->addAttribute( 'iframe', 'data-embedauthorid', 'Text' ); // used for embed notifications
|
||||
$def->addAttribute( 'iframe', 'data-embedauthorid', 'Number' ); // used for embed notifications
|
||||
$def->addAttribute( 'iframe', 'data-embedcontent', 'Text' ); // used in embeddableMedia
|
||||
$def->addAttribute( 'iframe', 'data-ipsembed-contentapp', 'Text' ); // used in embeddableMedia
|
||||
$def->addAttribute( 'iframe', 'data-ipsembed-contentid', 'Text' ); // used in embeddableMedia
|
||||
|
||||
@@ -138,6 +138,12 @@ abstract class Widget
|
||||
*/
|
||||
public bool $soloWidget = false;
|
||||
|
||||
/**
|
||||
* @brief Set to false if this widget should be hidden from the block list
|
||||
* in the Page Editor
|
||||
*/
|
||||
public static bool $showInBlockList = true;
|
||||
|
||||
/**
|
||||
* @brief If a widget should not be dropped into a particular area (e.g. a database widget in the header), list those areas here
|
||||
*/
|
||||
|
||||
Reference in new issue
Block a user