Version 5.0.0 beta 1

This commit is contained in:
Neo committed 2025-12-19 16:27:35 -08:00
1 parent 25ddeb65d6
commit 15c7beabc5
6736 files changed
+627902 -497943

No files matched your search

+35 -29
View File
@@ -12,48 +12,54 @@
namespace IPS\cms\widgets;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use Exception;
use IPS\cms\Blocks\Block;
use IPS\cms\Blocks\Container;
use IPS\Helpers\Form;
use IPS\Helpers\Form\Node;
use IPS\Widget\PermissionCache;
use OutOfRangeException;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Custom block Widget
*/
class _Blocks extends \IPS\Widget\PermissionCache
class Blocks extends PermissionCache
{
/**
* @brief Widget Key
*/
public $key = 'Blocks';
public string $key = 'Blocks';
/**
* @brief App
*/
public $app = 'cms';
/**
* @brief Plugin
*/
public $plugin = '';
public string $app = 'cms';
/**
* Constructor
*
* @param string $uniqueKey Unique key for this specific instance
* @param String $uniqueKey Unique key for this specific instance
* @param array $configuration Widget custom configuration
* @param null|string|array $access Array/JSON string of executable apps (core=sidebar only, content=IP.Content only, etc)
* @param null|string $orientation Orientation (top, bottom, right, left)
* @param array|string|null $access Array/JSON string of executable apps (core=sidebar only, content=IP.Content only, etc)
* @param string|null $orientation Orientation (top, bottom, right, left)
* @param string $layout
* @return void
*/
public function __construct( $uniqueKey, array $configuration, $access=null, $orientation=null )
public function __construct(string $uniqueKey, array $configuration, array|string $access=null, string $orientation=null, string $layout='table' )
{
try
{
if ( isset( $configuration['cms_widget_custom_block'] ) )
{
$block = \IPS\cms\Blocks\Block::load( $configuration['cms_widget_custom_block'], 'block_key' );
$block = Block::load( $configuration['cms_widget_custom_block'], 'block_key' );
if ( $block->type === 'custom' AND ! $block->cache )
{
$this->neverCache = TRUE;
@@ -66,22 +72,22 @@ class _Blocks extends \IPS\Widget\PermissionCache
$block->orientation = $orientation;
$block->widget()->init();
}
catch( \Exception $e ) { }
catch( Exception $e ) { }
}
}
}
catch( \Exception $e ) { }
catch( Exception $e ) { }
parent::__construct( $uniqueKey, $configuration, $access, $orientation );
parent::__construct( $uniqueKey, $configuration, $access, $orientation, $layout );
}
/**
* Specify widget configuration
*
* @param \IPS\Helpers\Form $form Form Object
* @return null|\IPS\Helpers\Form
* @param Form|null $form Form Object
* @return Form
*/
public function configuration( &$form=null )
public function configuration( Form &$form=null ): Form
{
$form = parent::configuration( $form );
@@ -91,17 +97,17 @@ class _Blocks extends \IPS\Widget\PermissionCache
{
if ( isset( $this->configuration['cms_widget_custom_block'] ) )
{
$block = \IPS\cms\Blocks\Block::load( $this->configuration['cms_widget_custom_block'], 'block_key' );
$block = Block::load( $this->configuration['cms_widget_custom_block'], 'block_key' );
}
}
catch( \OutOfRangeException $e ) { }
catch( OutOfRangeException $e ) { }
$form->add( new \IPS\Helpers\Form\Node( 'cms_widget_custom_block', $block, FALSE, array(
$form->add( new Node( 'cms_widget_custom_block', $block, FALSE, array(
'class' => '\IPS\cms\Blocks\Container',
'showAllNodes' => TRUE,
'permissionCheck' => function( $node )
{
if ( $node instanceof \IPS\cms\Blocks\Container )
if ( $node instanceof Container )
{
return FALSE;
}
@@ -119,7 +125,7 @@ class _Blocks extends \IPS\Widget\PermissionCache
* @param array $values Form values
* @return array
*/
public function preConfig( $values )
public function preConfig( array $values ): array
{
$newValues = $values;
@@ -136,11 +142,11 @@ class _Blocks extends \IPS\Widget\PermissionCache
*
* @return string
*/
public function render()
public function render(): string
{
if ( isset( $this->configuration['cms_widget_custom_block'] ) )
{
return (string) \IPS\cms\Blocks\Block::display( $this->configuration['cms_widget_custom_block'], $this->orientation );
return (string) Block::display( $this->configuration['cms_widget_custom_block'], $this->orientation );
}
return '';
+21 -18
View File
@@ -12,69 +12,72 @@
namespace IPS\cms\widgets;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use Exception;
use IPS\cms\Databases\Dispatcher;
use IPS\cms\Pages\Page;
use IPS\Http\Url;
use IPS\Widget\PermissionCache;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Categories Widget
*/
class _Categories extends \IPS\Widget\PermissionCache
class Categories extends PermissionCache
{
/**
* @brief Widget Key
*/
public $key = 'Categories';
public string $key = 'Categories';
/**
* @brief App
*/
public $app = 'cms';
/**
* @brief Plugin
*/
public $plugin = '';
public string $app = 'cms';
/**
* Render a widget
*
* @return string
*/
public function render()
public function render(): string
{
/* If we're not on a Pages page, return nothing */
if( !\IPS\cms\Pages\Page::$currentPage )
if( !Page::$currentPage )
{
return '';
}
/* Scope makes it possible for this block to fire before the main block which sets up the dispatcher */
$db = NULL;
if ( ! \IPS\cms\Databases\Dispatcher::i()->databaseId )
if ( ! Dispatcher::i()->databaseId )
{
try
{
$db = \IPS\cms\Pages\Page::$currentPage->getDatabase()->id;
$db = Page::$currentPage->getDatabase()->id;
}
catch( \Exception $ex )
catch( Exception $ex )
{
}
}
else
{
$db = \IPS\cms\Databases\Dispatcher::i()->databaseId;
$db = Dispatcher::i()->databaseId;
}
if ( ! \IPS\cms\Pages\Page::$currentPage->full_path or ! $db )
if ( ! Page::$currentPage->full_path or ! $db )
{
return '';
}
$url = \IPS\Http\Url::internal( "app=cms&module=pages&controller=page&path=" . \IPS\cms\Pages\Page::$currentPage->full_path, 'front', 'content_page_path', \IPS\cms\Pages\Page::$currentPage->full_path );
$url = Url::internal( "app=cms&module=pages&controller=page&path=" . Page::$currentPage->full_path, 'front', 'content_page_path', Page::$currentPage->full_path );
return $this->output($url);
}
+148
View File
@@ -0,0 +1,148 @@
<?php
/**
* @brief Codemirror Widget
* @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
{subpackage}
* @since 13 Dec 2023
*/
namespace IPS\cms\widgets;
use ErrorException;
use IPS\Data\Store;
use IPS\Helpers\Form;
use IPS\Http\Url;
use IPS\Log;
use IPS\Output;
use IPS\Theme;
use IPS\Widget;
use LogicException;
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;
}
/**
* RAW HTML Widget: Used to use CodeMirror, but now uses Tiptap in IPS v5
*/
class Codemirror extends Widget
{
/**
* @brief Widget Key
*/
public string $key = 'Codemirror';
/**
* @brief App
*/
public string $app = 'cms';
/**
* Specify widget configuration
*
* @param Form|NULL $form Form helper
* @return Form
*/
public function configuration( Form &$form=null ): Form
{
$form = parent::configuration( $form );
$form->add(
new Form\TextArea(
'content',
( isset( $this->configuration['content'] ) and $this->configuration['content'] ) ?
htmlentities( $this->configuration['content'], ENT_DISALLOWED, 'UTF-8' ) :
NULL,
FALSE,
[
'tagSource' => Url::internal( "app=cms&module=pages&controller=ajax&do=loadTags" ),
'codeMode' => true,
'codeModeAllowedLanguages' => ['ipsphtml']
],
function( $val )
{
try
{
Theme::checkTemplateSyntax( $val );
}
catch( LogicException $e )
{
throw new LogicException('cms_page_error_bad_syntax');
}
},
NULL,
NULL,
'page_content'
)
);
return $form;
}
/**
* Pre-save config method
*
* @param array $values Form values
* @return array
*/
public function preConfig( array $values=array() ) : array
{
$functionName = 'content_widget_' . $this->uniqueKey;
if ( isset( Store::i()->$functionName ) )
{
unset( Store::i()->$functionName );
}
return $values;
}
/**
* Before the widget is removed, we can do some clean up
*
* @return void
*/
public function delete() : void
{
$functionName = 'content_widget_' . $this->uniqueKey;
if ( isset( Store::i()->$functionName ) )
{
unset( Store::i()->$functionName );
}
}
/**
* Render a widget
*
* @return string
*/
public function render(): string
{
try
{
$functionName = 'content_widget_' . $this->uniqueKey;
if ( ! isset( Store::i()->$functionName ) )
{
Store::i()->$functionName = Theme::compileTemplate( $this->configuration['content'] ?? '', $functionName );
}
Theme::runProcessFunction( Store::i()->$functionName, $functionName );
$themeFunction = 'IPS\\Theme\\'. $functionName;
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, Output::i()->js( 'front_core.js', 'core' ) );
return $this->output( $themeFunction() );
}
catch( ErrorException $e )
{
Log::log( $e->getMessage(), 'codeblock' );
return "";
}
}
}
+44 -30
View File
@@ -12,77 +12,91 @@
namespace IPS\cms\widgets;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\cms\Databases;
use IPS\cms\Databases\Dispatcher;
use IPS\cms\Pages\Page;
use IPS\Helpers\Form;
use IPS\Helpers\Form\Select;
use IPS\Member;
use IPS\Request;
use IPS\Widget;
use OutOfRangeException;
use function count;
use function defined;
use function intval;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Database Widget
*/
class _Database extends \IPS\Widget
class Database extends Widget
{
/**
* @brief Widget Key
*/
public $key = 'Database';
public string $key = 'Database';
/**
* @brief App
*/
public $app = 'cms';
/**
* @brief Plugin
*/
public $plugin = '';
public string $app = 'cms';
/**
* @brief HTML if widget is called more than once, we store it.
*/
protected static $html = NULL;
protected static ?string $html = NULL;
/**
* @brief Set to true if this widget must be the only one in its area
*/
public bool $soloWidget = true;
/**
* Specify widget configuration
*
* @param \IPS\Helpers\Form|NULL $form Form helper
* @return null|\IPS\Helpers\Form
* @param Form|NULL $form Form helper
* @return Form
*/
public function configuration( &$form=null )
public function configuration( Form &$form=null ): Form
{
$form = parent::configuration( $form );
$databases = array();
$disabled = array();
foreach( \IPS\cms\Databases::databases() as $db )
foreach( Databases::databases() as $db )
{
$databases[ $db->id ] = $db->_title;
if ( $db->page_id and $db->page_id != \IPS\Request::i()->pageID )
if ( $db->page_id and $db->page_id != Request::i()->pageID )
{
$disabled[] = $db->id;
try
{
$page = \IPS\cms\Pages\Page::load( $db->page_id );
$databases[ $db->id ] = \IPS\Member::loggedIn()->language()->addToStack( 'cms_db_in_use_by_page', FALSE, array( 'sprintf' => array( $db->_title, $page->full_path ) ) );
$page = Page::load( $db->page_id );
$databases[ $db->id ] = Member::loggedIn()->language()->addToStack( 'cms_db_in_use_by_page', FALSE, array( 'sprintf' => array( $db->_title, $page->full_path ) ) );
}
catch( \OutOfRangeException $ex )
catch( OutOfRangeException $ex )
{
unset( $databases[ $db->id ] );
}
}
}
if ( ! \count( $databases ) )
if ( ! count( $databases ) )
{
$form->addMessage('cms_err_no_databases_to_use');
}
else
{
$form->add( new \IPS\Helpers\Form\Select( 'database', ( isset( $this->configuration['database'] ) ? (int) $this->configuration['database'] : NULL ), FALSE, array( 'options' => $databases, 'disabled' => $disabled ) ) );
$form->add( new Select( 'database', ( isset( $this->configuration['database'] ) ? (int) $this->configuration['database'] : NULL ), FALSE, array( 'options' => $databases, 'disabled' => $disabled ) ) );
}
return $form;
@@ -94,11 +108,11 @@ class _Database extends \IPS\Widget
* @param array $values Form values
* @return array
*/
public function preConfig( $values )
public function preConfig( array $values ): array
{
if ( \IPS\Request::i()->pageID and $values['database'] )
if ( Request::i()->pageID and $values['database'] )
{
\IPS\cms\Pages\Page::load( \IPS\Request::i()->pageID )->mapToDatabase( $values['database'] );
Page::load( Request::i()->pageID )->mapToDatabase( $values['database'] );
}
return $values;
@@ -109,7 +123,7 @@ class _Database extends \IPS\Widget
*
* @return string
*/
public function render()
public function render(): string
{
if ( static::$html === NULL )
{
@@ -117,17 +131,17 @@ class _Database extends \IPS\Widget
{
try
{
$database = \IPS\cms\Databases::load( \intval( $this->configuration['database'] ) );
$database = Databases::load( intval( $this->configuration['database'] ) );
if ( ! $database->page_id and \IPS\cms\Pages\Page::$currentPage )
if ( ! $database->page_id and Page::$currentPage )
{
$database->page_id = \IPS\cms\Pages\Page::$currentPage->id;
$database->page_id = Page::$currentPage->id;
$database->save();
}
static::$html = \IPS\cms\Databases\Dispatcher::i()->setDatabase( $database->id )->run();
static::$html = Dispatcher::i()->setDatabase( $database->id )->run();
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException $e )
{
static::$html = '';
}
+85 -54
View File
@@ -12,75 +12,90 @@
namespace IPS\cms\widgets;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use Exception;
use IPS\cms\Categories;
use IPS\cms\Databases;
use IPS\cms\Databases\Dispatcher;
use IPS\cms\Fields;
use IPS\DateTime;
use IPS\Helpers\Form;
use IPS\Helpers\Form\Checkbox;
use IPS\Helpers\Form\CheckboxSet;
use IPS\Helpers\Form\DateRange;
use IPS\Helpers\Form\YesNo;
use IPS\Member;
use IPS\Output;
use IPS\Request;
use IPS\Widget;
use OutOfRangeException;
use function count;
use function defined;
use function in_array;
use function intval;
use function is_array;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* LatestArticles Widget
*/
class _DatabaseFilters extends \IPS\Widget
class DatabaseFilters extends Widget
{
/**
* @brief Widget Key
*/
public $key = 'DatabaseFilters';
public string $key = 'DatabaseFilters';
/**
* @brief App
*/
public $app = 'cms';
/**
* @brief Plugin
*/
public $plugin = '';
public string $app = 'cms';
/**
* Render a widget
*
* @return string
*/
public function render()
public function render(): string
{
/* Viewing or adding/editing a record */
if ( \IPS\cms\Databases\Dispatcher::i()->recordId or \IPS\Request::i()->do == 'form' )
if ( Dispatcher::i()->recordId or Request::i()->do == 'form' )
{
return '';
}
if ( ! \IPS\cms\Databases\Dispatcher::i()->databaseId AND ! \IPS\cms\Databases\Dispatcher::i()->categoryId )
if ( ! Dispatcher::i()->databaseId AND ! Dispatcher::i()->categoryId )
{
return '';
}
try
{
$database = \IPS\cms\Databases::load( \IPS\cms\Databases\Dispatcher::i()->databaseId );
$database = Databases::load( Dispatcher::i()->databaseId );
$database->preLoadWords();
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException $e )
{
return '';
}
try
{
$categoryClass = "IPS\cms\Categories" . \IPS\cms\Databases\Dispatcher::i()->databaseId;
$category = $categoryClass::load( \IPS\cms\Databases\Dispatcher::i()->categoryId );
/* @var Categories $categoryClass */
$categoryClass = "IPS\cms\Categories" . Dispatcher::i()->databaseId;
$category = $categoryClass::load( Dispatcher::i()->categoryId );
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException $e )
{
return '';
}
if ( ! $database->use_categories AND $database->cat_index_type !== 0 )
{
return '';
}
/* @var Fields $fieldClass */
$fieldClass = 'IPS\cms\Fields' . $database->id;
$fields = array();
@@ -90,7 +105,7 @@ class _DatabaseFilters extends \IPS\Widget
$urlValues = array();
foreach( \IPS\Request::i() as $k => $v )
foreach( Request::i() as $k => $v )
{
if( mb_strpos( $k, 'content_field_' ) !== FALSE )
{
@@ -104,11 +119,11 @@ class _DatabaseFilters extends \IPS\Widget
if ( isset( $databaseFields[ $fieldId ] ) and $databaseFields[ $fieldId ]->type == 'Member' )
{
$urlValues[ str_replace( 'content_', '', $k ) ] = \is_array( $v ) ? implode( '\n', $v ) : $v;
$urlValues[ str_replace( 'content_', '', $k ) ] = is_array( $v ) ? implode( '\n', $v ) : $v;
}
else
{
$urlValues[ str_replace( 'content_', '', $k ) ] = \is_array( $v ) ? implode( ',', $v ) : $v;
$urlValues[ str_replace( 'content_', '', $k ) ] = is_array( $v ) ? implode( ',', $v ) : $v;
}
}
}
@@ -121,14 +136,14 @@ class _DatabaseFilters extends \IPS\Widget
if ( $field->type === 'Member' and isset( $cookieValues[ 'field_' . $field->id ] ) )
{
$members = array();
$memberArray = \is_array( $cookieValues[ 'field_' . $field->id ] ) ? $cookieValues[ 'field_' . $field->id ] : explode( '\n', $cookieValues[ 'field_' . $field->id ] );
$memberArray = is_array( $cookieValues[ 'field_' . $field->id ] ) ? $cookieValues[ 'field_' . $field->id ] : explode( '\n', $cookieValues[ 'field_' . $field->id ] );
foreach( $memberArray as $id )
{
try
{
$members[] = \IPS\Member::load( $id );
$members[] = Member::load( $id );
}
catch( \Exception $e ) { }
catch( Exception $e ) { }
}
$cookieValues[ 'field_' . $field->id ] = $members;
@@ -136,20 +151,31 @@ class _DatabaseFilters extends \IPS\Widget
}
foreach( $fieldClass::fields( $cookieValues, 'view', $category, $fieldClass::FIELD_SKIP_TITLE_CONTENT | $fieldClass::FIELD_DISPLAY_FILTERS, NULL, FALSE ) as $id => $field )
{
/* If this is a select field, remove "other" from the list */
if( $field instanceof Form\Select )
{
$options = $field->options;
if( $userSuppliedInput = $options['userSuppliedInput'] )
{
unset( $options['options'][ $userSuppliedInput ] );
$options['userSuppliedInput'] = null;
}
$field->options = $options;
}
/* Force a unique ID to prevent other areas using this same field htmlID */
$field->htmlId = $field->name .'_' . md5( uniqid() );
$fields[ $id ] = $field;
}
if ( \count( $fields ) )
if ( count( $fields ) )
{
$form = new \IPS\Helpers\Form( 'category_filters', 'update', $category->url() );
$form->class = 'ipsForm_vertical';
if ( \IPS\Request::i()->sortby )
$form = new Form( 'category_filters', 'update', $category->url() );
$form->class = 'ipsForm--vertical ipsForm--database-widget-filters';
if ( Request::i()->sortby )
{
$form->hiddenValues['sortby'] = \IPS\Request::i()->sortby;
$form->hiddenValues['sortdirection'] = isset( \IPS\Request::i()->sortdirection ) ? \IPS\Request::i()->sortdirection : 'desc';
$form->hiddenValues['sortby'] = Request::i()->sortby;
$form->hiddenValues['sortdirection'] = isset( Request::i()->sortdirection ) ? Request::i()->sortdirection : 'desc';
}
else
{
@@ -165,7 +191,7 @@ class _DatabaseFilters extends \IPS\Widget
$form->add( $field );
}
if ( \IPS\Member::loggedIn()->member_id )
if ( Member::loggedIn()->member_id )
{
$iStarted = FALSE;
if ( isset( $cookie['cms_record_i_started'] ) and $cookie['cms_record_i_started'] )
@@ -174,15 +200,20 @@ class _DatabaseFilters extends \IPS\Widget
}
/* Form submission takes preference over any previously stored cookie values */
if ( ( isset( \IPS\Request::i()->cms_record_i_started ) and \IPS\Request::i()->cms_record_i_started ) )
if ( ( isset( Request::i()->cms_record_i_started ) and Request::i()->cms_record_i_started ) )
{
$iStarted = TRUE;
}
$form->add( new \IPS\Helpers\Form\Checkbox( 'cms_record_i_started', $iStarted, FALSE ) );
$form->add( new Checkbox( 'cms_record_i_started', $iStarted, FALSE ) );
/* we need this language later (and in Widgets\DatabaseFilters which is executed just before output) */
Member::loggedIn()->language()->words['cms_record_i_started'] = Member::loggedIn()->language()->addToStack( 'cms_record_i_started_sprintf', FALSE, array( 'sprintf' => $database->recordWord() ) );
}
$form->add( new \IPS\Helpers\Form\Checkbox( 'cms_widget_filters_remember', ( $cookie !== NULL ) ? TRUE : FALSE, FALSE, array( 'label' => 'cms_widget_filters_remember_text') ) );
$field = new Checkbox( 'cms_widget_filters_remember', $cookie !== null, false );
$field->label = Member::loggedIn()->language()->addToStack( 'cms_widget_filters_remember_text' );
$form->add( $field );
if ( $values = $form->values() )
{
@@ -195,31 +226,31 @@ class _DatabaseFilters extends \IPS\Widget
{
$id = mb_substr( $k, 14 );
if ( isset( $fields[ $id ] ) and $fields[ $id ] instanceof \IPS\Helpers\Form\CheckboxSet )
if ( isset( $fields[ $id ] ) and $fields[ $id ] instanceof CheckboxSet )
{
/* We need to reformat this a little */
$v = array_combine( $v, $v );
}
else if ( isset( $fields[ $id ] ) and $fields[ $id ] instanceof \IPS\Helpers\Form\YesNo )
else if ( isset( $fields[ $id ] ) and $fields[ $id ] instanceof YesNo )
{
/* The form class looks for {$name}_checkbox to determine the value */
$k = $k . '_checkbox';
}
else if ( isset( $fields[ $id ] ) and $fields[ $id ] instanceof \IPS\Helpers\Form\DateRange )
else if ( isset( $fields[ $id ] ) and $fields[ $id ] instanceof DateRange )
{
/* We need to reformat this a little */
$start = ( $v['start'] instanceof \IPS\DateTime ) ? $v['start']->getTimestamp() : \intval( $v['start'] );
$end = ( $v['end'] instanceof \IPS\DateTime ) ? $v['end']->getTimestamp() : \intval( $v['end'] );
$start = ( $v['start'] instanceof DateTime ) ? $v['start']->getTimestamp() : intval( $v['start'] );
$end = ( $v['end'] instanceof DateTime ) ? $v['end']->getTimestamp() : intval( $v['end'] );
$v = array( 'start' => $start, 'end' => $end );
}
else if ( isset( $fields[ $id ] ) and $fields[ $id ] instanceof \IPS\Helpers\Form\Member )
else if ( isset( $fields[ $id ] ) and $fields[ $id ] instanceof Form\Member )
{
$ids = array();
if ( \is_array( $v ) )
if ( is_array( $v ) )
{
foreach( $v as $member )
{
if ( $member instanceof \IPS\Member )
if ( $member instanceof Member )
{
$ids[] = $member->member_id;
}
@@ -227,7 +258,7 @@ class _DatabaseFilters extends \IPS\Widget
$v = $ids;
}
else if ( $v instanceof \IPS\Member )
else if ( $v instanceof Member )
{
$v = $v->member_id;
}
@@ -244,13 +275,13 @@ class _DatabaseFilters extends \IPS\Widget
}
}
if ( \count( $form->hiddenValues ) )
if ( count( $form->hiddenValues ) )
{
foreach( $form->hiddenValues as $k => $v )
{
if ( $k !== 'csrfKey' )
{
if ( !\in_array( $k, array( 'sortby', 'sortdirection' ) ) )
if ( !in_array( $k, array( 'sortby', 'sortdirection' ) ) )
{
$cookie[ $k ] = $v;
}
@@ -262,13 +293,13 @@ class _DatabaseFilters extends \IPS\Widget
if ( $values['cms_widget_filters_remember'] )
{
$category->saveFilterCookie( $cookie );
\IPS\Output::i()->redirect( $category->url() );
Output::i()->redirect( $category->url() );
}
else
{
/* Remove the filter cookie */
$category->saveFilterCookie( FALSE );
\IPS\Output::i()->redirect( $url->setQueryString( $params ) );
Output::i()->redirect( $url->setQueryString( $params ) );
}
}
@@ -0,0 +1,99 @@
<?php
/**
* @brief DatabaseNavigation Widget
* @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
{subpackage}
* @since 03 Jan 2024
*/
namespace IPS\cms\widgets;
use IPS\cms\Categories;
use IPS\cms\Databases;
use IPS\cms\Databases\Dispatcher;
use IPS\Output;
use IPS\Request;
use IPS\Widget\PermissionCache;
use OutOfRangeException;
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;
}
/**
* DatabaseNavigation Widget
*/
class DatabaseNavigation extends PermissionCache
{
/**
* @brief Widget Key
*/
public string $key = 'DatabaseNavigation';
/**
* @brief App
*/
public string $app = 'cms';
/**
* Initialise this widget
*
* @return void
*/
public function init(): void
{
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, Output::i()->js( 'front_blocks.js', 'cms', 'front' ) );
parent::init();
}
/**
* Render a widget
*
* @return string
*/
public function render(): string
{
/* adding/editing a record */
if ( Request::i()->do == 'form' )
{
return '';
}
if ( ! Dispatcher::i()->databaseId )
{
return '';
}
try
{
$database = Databases::load( Dispatcher::i()->databaseId );
$database->preLoadWords();
}
catch ( OutOfRangeException $e )
{
return '';
}
/* @var Categories $categoriesClass */
$categoriesClass = 'IPS\cms\Categories' . $database->id;
if( $database->use_categories )
{
$categories = $categoriesClass::roots();
}
else
{
$categories = $categoriesClass::load( $database->default_category );
}
return $this->output( $database, $categories, Dispatcher::i()->categoryId );
}
}
@@ -0,0 +1,129 @@
<?php
/**
* @brief FolderNavigation Widget
* @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
{subpackage}
* @since 04 Jan 2024
*/
namespace IPS\cms\widgets;
use IPS\cms\Pages\Folder;
use IPS\cms\Pages\Page;
use IPS\Db;
use IPS\Helpers\Form;
use IPS\Helpers\Form\Node;
use IPS\Helpers\Form\Text;
use IPS\Output;
use IPS\Patterns\ActiveRecordIterator;
use IPS\Widget;
use OutOfRangeException;
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;
}
/**
* FolderNavigation Widget
*/
class FolderNavigation extends Widget
{
/**
* @brief Widget Key
*/
public string $key = 'FolderNavigation';
/**
* @brief App
*/
public string $app = 'cms';
/**
* Initialise this widget
*
* @return void
*/
public function init() : void
{
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, Output::i()->js( 'front_blocks.js', 'cms', 'front' ) );
parent::init();
}
/**
* Specify widget configuration
*
* @param null|Form $form Form object
* @return Form
*/
public function configuration( Form &$form=null ): Form
{
$form = parent::configuration( $form );
$form->add( new Text( 'block_nav_title', $this->configuration['block_nav_title'] ?? null, true ) );
$form->add( new Node( 'block_nav_folder', $this->configuration['block_nav_folder'] ?? 0, true, array(
'class' => Folder::class,
'multiple' => false,
'zeroVal' => 'cms_navigation_root_folder'
) ) );
return $form;
}
/**
* Ran before saving widget configuration
*
* @param array $values Values from form
* @return array
*/
public function preConfig( array $values ): array
{
$values['block_nav_folder'] = ( $values['block_nav_folder'] instanceof Folder ) ? $values['block_nav_folder']->_id : 0;
return $values;
}
/**
* Render a widget
*
* @return string
*/
public function render(): string
{
if( !Page::$currentPage )
{
return "";
}
$rootId = $this->configuration['block_nav_folder'] ?? 0;
if( $rootId !== 0 )
{
try
{
$folders = Folder::load( $this->configuration['block_nav_folder'] );
}
catch( OutOfRangeException )
{
return "";
}
}
else
{
$folders = Folder::roots();
}
$pages = iterator_to_array(
new ActiveRecordIterator(
Db::i()->select( '*', 'cms_pages', [ 'page_folder_id=?', $rootId ] ),
Page::class
)
);
return $this->output( $folders, $rootId, $pages, $this->configuration['block_nav_title'] ?? null, Page::$currentPage->folder_id ?: null );
}
}
+165 -138
View File
@@ -13,142 +13,201 @@ namespace IPS\cms\widgets;
/* To prevent PHP errors (extending class does not exist) revealing path */
use ErrorException;
use IPS\cms\Databases;
use IPS\cms\Fields;
use IPS\Content\Widget;
use IPS\DateTime;
use IPS\Db;
use IPS\Helpers\Form;
use IPS\Helpers\Form\Select;
use IPS\Helpers\Form\Text;
use IPS\Member;
use IPS\Request;
use IPS\Settings;
use IPS\Theme;
use OutOfRangeException;
use function count;
use function defined;
use function get_called_class;
use function in_array;
use function intval;
use function is_array;
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* RecordFeed Widget
*/
class _RecordFeed extends \IPS\Content\Widget
class RecordFeed extends Widget
{
/**
* @brief Widget Key
*/
public $key = 'RecordFeed';
public string $key = 'RecordFeed';
/**
* @brief App
*/
public $app = 'cms';
/**
* @brief Plugin
*/
public $plugin = '';
public string $app = 'cms';
/**
* Class
*/
protected static $class = 'IPS\cms\Records';
protected static string $class = 'IPS\cms\Records';
/**
* @var int|null
*/
public static ?int $customDatabaseId = null;
/**
* Constructor
*
* @param String $uniqueKey Unique key for this specific instance
* @param array $configuration Widget custom configuration
* @param array|string|null $access Array/JSON string of executable apps (core=sidebar only, content=IP.Content only, etc)
* @param string|null $orientation Horizontal or vertical orientation
* @param string $layout Current layout in use
* @return void
*/
public function __construct( string $uniqueKey, array $configuration, array|string $access=null, string $orientation=null, string $layout='' )
{
/* If we called this class directly and we have a database ID, call the child class.
We do this so that we can support existing widgets. */
if( get_called_class() == 'IPS\cms\widgets\RecordFeed' and isset( $configuration['cms_rf_database'] ) )
{
$widgetClass = 'IPS\cms\widgets\RecordFeed' . $configuration['cms_rf_database'];
return new $widgetClass( $uniqueKey, $configuration, $access, $orientation, $layout );
}
parent::__construct( $uniqueKey, $configuration, $access, $orientation, $layout );
/* Force the database to be set to the DatabaseID */
if( !isset( $this->configuration['cms_rf_database'] ) )
{
$this->configuration['cms_rf_database'] = static::$customDatabaseId;
}
$this->key = 'RecordFeed' . static::$customDatabaseId;
static::$class = 'IPS\cms\Records' . static::$customDatabaseId;
/* Load block title and description */
Member::loggedIn()->language()->words[ 'block_RecordFeed' . static::$customDatabaseId ] = Member::loggedIn()->language()->addToStack( 'cms_db_feed_block_with_name', FALSE, array('sprintf' => array( Member::loggedIn()->language()->addToStack('content_db_' . static::$customDatabaseId ) ) ) );
Member::loggedIn()->language()->words[ 'block_RecordFeed' . static::$customDatabaseId . '_desc' ] = Member::loggedIn()->language()->addToStack( 'cms_db_feed_block_with_name_desc', false, array( 'sprintf' => array( Member::loggedIn()->language()->addToStack( 'content_db_lang_pl_' . static::$customDatabaseId ) ) ) );
}
/**
* Initialise this widget
*
* @return void
* @throws ErrorException
*/
public function init(): void
{
$this->template( array( Theme::i()->getTemplate( 'widgets', 'cms', 'front' ), 'RecordFeed' ) );
}
/**
* @return Databases|null
*/
protected function database() : ?Databases
{
if( static::$customDatabaseId )
{
return Databases::load( static::$customDatabaseId );
}
elseif( isset( $this->configuration['cms_rf_database'] ) )
{
return Databases::load( $this->configuration['cms_rf_database'] );
}
return null;
}
/**
* Specify widget configuration
*
* @param null|\IPS\Helpers\Form $form Form object
* @return null|\IPS\Helpers\Form
* @param Form|null $form Form object
* @return Form
*/
public function configuration( &$form=null )
public function configuration( Form &$form=null ): Form
{
$databases = array();
$database = NULL;
foreach( \IPS\cms\Databases::databases() as $obj )
{
if ( $obj->page_id )
{
$databases[ $obj->_id ] = $obj->_title;
}
if ( ( isset( \IPS\Request::i()->cms_rf_database ) AND $obj->id == \IPS\Request::i()->cms_rf_database ) OR ( ( isset( $this->configuration['cms_rf_database'] ) AND $obj->id == $this->configuration['cms_rf_database'] ) ) )
{
$database = $obj;
static::$class = '\IPS\cms\Records' . $database->id;
}
}
$form = parent::configuration( $form );
if ( isset( $this->configuration['cms_rf_database'] ) )
{
$form->addDummy( 'cms_rf_database', $database->_title, \IPS\Member::loggedIn()->language()->addToStack( 'cms_rf_database_description' ) );
$form->hiddenValues['cms_rf_database'] = $database->_id;
}
else
{
$form->add( new \IPS\Helpers\Form\Select( 'cms_rf_database', 0, FALSE, array(
'disabled' => false,
'options' => $databases
) ) );
}
$database = $this->database();
$form = parent::configuration( $form );
$form->addDummy( 'cms_rf_database', $database->_title, Member::loggedIn()->language()->addToStack( 'cms_rf_database_description' ) );
$form->hiddenValues['cms_rf_database'] = $database->_id;
$class = static::$class;
/* If the database does not use categories, hide that field from the form */
if( $database and !$database->use_categories and isset( $form->elements['']['widget_feed_container_' . $class::$title ] ) )
{
unset( $form->elements['']['widget_feed_container_' . $class::$title ] );
}
/* Sort */
$sortOptions = array(
'primary_id_field' => 'database_field__id',
'member_id' => 'database_field__member',
'record_publish_date' => 'database_field__saved',
'record_updated' => ( $database and $database->_comment_bump === Databases::BUMP_ON_EDIT ) ? 'database_field__edited' : 'database_field__updated',
'record_last_comment' => 'sort_record_last_comment',
'record_rating' => 'database_field__rating'
);
/* @var array $databaseColumnMap */
foreach ( array( 'num_comments', 'views', 'rating_average' ) as $k )
{
if ( isset( $class::$databaseColumnMap[ $k ] ) )
{
$sortOptions[ $class::$databaseColumnMap[ $k ] ] = 'sort_' . $k;
}
}
/* Tags */
if ( $database )
{
/* Sort */
$sortOptions = array(
'primary_id_field' => 'database_field__id',
'member_id' => 'database_field__member',
'record_publish_date' => 'database_field__saved',
'record_updated' => ( $database and $database->_comment_bump === \IPS\cms\Databases::BUMP_ON_EDIT ) ? 'database_field__edited' : 'database_field__updated',
'record_last_comment' => 'sort_record_last_comment',
'record_rating' => 'database_field__rating'
);
$class = static::$class;
foreach ( array( 'num_comments', 'views', 'rating_average' ) as $k )
{
if ( isset( $class::$databaseColumnMap[ $k ] ) )
{
$sortOptions[ $class::$databaseColumnMap[ $k ] ] = 'sort_' . $k;
}
}
/* @var Fields $fieldsClass */
$fieldsClass = '\IPS\cms\Fields' . $database->id;
if ( $database )
foreach( $fieldsClass::data() as $id => $field )
{
$FieldsClass = '\IPS\cms\Fields' . $database->id;
foreach( $FieldsClass::data() as $id => $field )
if ( in_array( $field->type, array( 'checkbox', 'multiselect', 'attachments' ) ) )
{
if ( \in_array( $field->type, array( 'checkbox', 'multiselect', 'attachments' ) ) )
{
continue;
}
$sortOptions[ 'field_' . $field->id ] = $field->_title;
continue;
}
}
$form->add( new \IPS\Helpers\Form\Select( 'widget_feed_sort_on', isset( $this->configuration['widget_feed_sort_on'] ) ? $this->configuration['widget_feed_sort_on'] : $class::$databaseColumnMap['updated'], FALSE, array( 'options' => $sortOptions ) ), NULL, NULL, NULL, 'widget_feed_sort_on' );
$sortOptions[ 'field_' . $field->id ] = $field->_title;
}
if ( $database->tags_enabled )
{
$options = array( 'autocomplete' => array( 'unique' => TRUE, 'source' => NULL, 'freeChoice' => TRUE ) );
if ( \IPS\Settings::i()->tags_force_lower )
if ( Settings::i()->tags_force_lower )
{
$options['autocomplete']['forceLower'] = TRUE;
}
if ( \IPS\Settings::i()->tags_clean )
{
$options['autocomplete']['filterProfanity'] = TRUE;
}
$options['autocomplete']['prefix'] = FALSE;
$form->add( new \IPS\Helpers\Form\Text( 'widget_feed_tags', ( isset( $this->configuration['widget_feed_tags'] ) ? $this->configuration['widget_feed_tags'] : array( 'tags' => NULL ) ), FALSE, $options ) );
$form->add( new Text( 'widget_feed_tags', ( $this->configuration['widget_feed_tags'] ?? array( 'tags' => NULL ) ), FALSE, $options ) );
}
}
$form->add( new Select( 'widget_feed_sort_on', $this->configuration['widget_feed_sort_on'] ?? $class::$databaseColumnMap['updated'], FALSE, array( 'options' => $sortOptions ), NULL, NULL, NULL, 'widget_feed_sort_on' ) );
/* Any filterable fields */
if ( $database )
{
/* @var Fields $fieldClass */
$fieldClass = 'IPS\cms\Fields' . $database->id;
foreach( $fieldClass::fields( $this->_getCustomValuesFromConfiguration(), 'view', NULL, $fieldClass::FIELD_SKIP_TITLE_CONTENT | $fieldClass::FIELD_DISPLAY_FILTERS ) as $id => $field )
{
@@ -158,11 +217,11 @@ class _RecordFeed extends \IPS\Content\Widget
if ( $database )
{
\IPS\Member::loggedIn()->language()->words['widget_feed_container_content_db_lang_su_' . $database->id ] = \IPS\Member::loggedIn()->language()->addToStack('widget_feed_container_cms');
Member::loggedIn()->language()->words['widget_feed_container_content_db_lang_su_' . $database->id ] = Member::loggedIn()->language()->addToStack('widget_feed_container_cms');
if ( $database->_comment_bump === \IPS\cms\Databases::BUMP_ON_EDIT )
if ( $database->_comment_bump === Databases::BUMP_ON_EDIT )
{
\IPS\Member::loggedIn()->language()->words['sort_updated'] = \IPS\Member::loggedIn()->language()->addToStack('database_field__edited');
Member::loggedIn()->language()->words['sort_updated'] = Member::loggedIn()->language()->addToStack('database_field__edited');
}
}
@@ -175,7 +234,7 @@ class _RecordFeed extends \IPS\Content\Widget
* @param boolean $keyAsInt Returns an array with just the field ID, as opposed to 'field_x'
* @return array
*/
protected function _getCustomValuesFromConfiguration( $keyAsInt=false )
protected function _getCustomValuesFromConfiguration( bool $keyAsInt=false ) : array
{
$customValues = array();
foreach( $this->configuration as $k => $v )
@@ -195,17 +254,17 @@ class _RecordFeed extends \IPS\Content\Widget
* @param array $values Values from form
* @return array
*/
public function preConfig( $values )
public function preConfig( array $values ): array
{
static::$class = '\IPS\cms\Records' . $values['cms_rf_database'];
static::$class = '\IPS\cms\Records' . static::$customDatabaseId;
foreach( $values as $k => $v )
{
/* We need to reformat this a little */
if ( \is_array( $v ) and isset( $v['start'] ) and isset( $v['end'] ) )
if ( is_array( $v ) and isset( $v['start'] ) and isset( $v['end'] ) )
{
$start = ( $v['start'] instanceof \IPS\DateTime ) ? $v['start']->getTimestamp() : \intval( $v['start'] );
$end = ( $v['end'] instanceof \IPS\DateTime ) ? $v['end']->getTimestamp() : \intval( $v['end'] );
$start = ( $v['start'] instanceof DateTime ) ? $v['start']->getTimestamp() : intval( $v['start'] );
$end = ( $v['end'] instanceof DateTime ) ? $v['end']->getTimestamp() : intval( $v['end'] );
$values[ $k ] = array( 'start' => $start, 'end' => $end );
}
@@ -219,32 +278,14 @@ class _RecordFeed extends \IPS\Content\Widget
*
* @return array
*/
protected function buildWhere()
protected function buildWhere(): array
{
static::$class = '\IPS\cms\Records' . $this->configuration['cms_rf_database'];
$class = static::$class;
static::$class = '\IPS\cms\Records' . static::$customDatabaseId;
$where = parent::buildWhere();
/* If we did not select any categories and we are honoring permissions, filter out club categories */
if( empty( $this->configuration['widget_feed_container'] ) and !empty( $this->configuration['widget_feed_use_perms'] ) )
{
$database = \IPS\cms\Databases::load( $this->configuration['cms_rf_database'] );
if( $database->use_categories and $database->allow_club_categories )
{
/* Loop through and get only the categories that the user can view */
$nodes = [];
$categoriesClass = 'IPS\cms\Categories' . $this->configuration['cms_rf_database'];
foreach( $categoriesClass::roots( 'read' ) as $cat )
{
$nodes[] = $cat->_id;
}
$where[] = [ Db::i()->in( $class::$databaseTable . '.category_id', $nodes ) ];
}
}
$fieldClass = 'IPS\cms\Fields' . $this->configuration['cms_rf_database'];
/* @var Fields $fieldClass */
$fieldClass = 'IPS\cms\Fields' . static::$customDatabaseId;
$customFields = $fieldClass::data( 'view', NULL, $fieldClass::FIELD_SKIP_TITLE_CONTENT | $fieldClass::FIELD_DISPLAY_FILTERS );
foreach( $this->_getCustomValuesFromConfiguration( TRUE ) as $f => $v )
@@ -252,12 +293,12 @@ class _RecordFeed extends \IPS\Content\Widget
$k = 'field_' . $f;
if ( isset( $customFields[ $f ] ) and $v !== '___any___' AND $v !== NULL )
{
if ( \is_array( $v ) )
if ( is_array( $v ) )
{
if ( array_key_exists( 'start', $v ) or array_key_exists( 'end', $v ) )
{
$start = ( $v['start'] instanceof \IPS\DateTime ) ? $v['start']->getTimestamp() : \intval( $v['start'] );
$end = ( $v['end'] instanceof \IPS\DateTime ) ? $v['end']->getTimestamp() : \intval( $v['end'] );
$start = ( $v['start'] instanceof DateTime ) ? $v['start']->getTimestamp() : intval( $v['start'] );
$end = ( $v['end'] instanceof DateTime ) ? $v['end']->getTimestamp() : intval( $v['end'] );
if ( $start or $end )
{
@@ -267,17 +308,17 @@ class _RecordFeed extends \IPS\Content\Widget
else
{
$like = array();
if ( \count( $v ) )
if ( count( $v ) )
{
foreach( $v as $val )
{
if ( $val === 0 or ! empty( $val ) )
{
$like[] = "CONCAT( ',', " . $k . ", ',') LIKE '%," . \IPS\Db::i()->real_escape_string( $val ) . ",%'";
$like[] = "CONCAT( ',', " . $k . ", ',') LIKE '%," . Db::i()->real_escape_string( $val ) . ",%'";
}
}
$where[] = array( '( ' . \IPS\Db::i()->in( $k, $v ) . ( \count( $like ) ? " OR (" . implode( ' OR ', $like ) . ') )' : ')' ) );
$where[] = array( '( ' . Db::i()->in( $k, $v ) . ( count( $like ) ? " OR (" . implode( ' OR ', $like ) . ') )' : ')' ) );
}
}
}
@@ -307,30 +348,16 @@ class _RecordFeed extends \IPS\Content\Widget
*
* @return string
*/
public function render()
public function render(): string
{
if( isset( $this->configuration['cms_rf_database'] ) )
if( $database = $this->database() )
{
try
if( $database->page_id )
{
$database = \IPS\cms\Databases::load($this->configuration['cms_rf_database']);
static::$class = '\IPS\cms\Records' . $database->id;
if ( ! $database->page_id )
{
throw new \OutOfRangeException;
}
return parent::render();
}
catch ( \OutOfRangeException $e )
{
return '';
}
}
else
{
return '';
}
return parent::render();
return '';
}
}
+36 -27
View File
@@ -12,31 +12,40 @@
namespace IPS\cms\widgets;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use Exception;
use IPS\Data\Store;
use IPS\DateTime;
use IPS\Helpers\Form;
use IPS\Helpers\Form\Number;
use IPS\Helpers\Form\Text;
use IPS\Http\Url;
use IPS\Member;
use IPS\Text\Parser;
use IPS\Widget\Customizable;
use IPS\Widget\StaticCache;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Rss Widget
*/
class _Rss extends \IPS\Widget\StaticCache
class Rss extends StaticCache implements Customizable
{
/**
* @brief Widget Key
*/
public $key = 'Rss';
public string $key = 'Rss';
/**
* @brief App
*/
public $app = 'cms';
/**
* @brief Plugin
*/
public $plugin = '';
public string $app = 'cms';
/**
* Constructor
@@ -56,20 +65,20 @@ class _Rss extends \IPS\Widget\StaticCache
}
}
/**
/**
* Specify widget configuration
*
* @param null|\IPS\Helpers\Form $form Form object
* @return null|\IPS\Helpers\Form
* @param null|Form $form Form object
* @return Form
*/
public function configuration( &$form=null )
public function configuration( Form &$form=null ): Form
{
$form = parent::configuration( $form );
$form->add( new \IPS\Helpers\Form\Text( 'block_rss_import_title', ( isset( $this->configuration['block_rss_import_title'] ) ? $this->configuration['block_rss_import_title'] : NULL ), TRUE ) );
$form->add( new \IPS\Helpers\Form\Url( 'block_rss_import_url', ( isset( $this->configuration['block_rss_import_url'] ) ? $this->configuration['block_rss_import_url'] : NULL ), TRUE ) );
$form->add( new \IPS\Helpers\Form\Number( 'block_rss_import_number', ( isset( $this->configuration['block_rss_import_number'] ) ? $this->configuration['block_rss_import_number'] : 5 ), TRUE ) );
$form->add( new \IPS\Helpers\Form\Number( 'block_rss_import_cache', ( isset( $this->configuration['block_rss_import_cache'] ) ? $this->configuration['block_rss_import_cache'] : 30 ), TRUE, array(), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack('block_rss_import_cache_suffix') ) );
$form->add( new Text( 'block_rss_import_title', ( $this->configuration['block_rss_import_title'] ?? NULL ), TRUE ) );
$form->add( new Form\Url( 'block_rss_import_url', ( $this->configuration['block_rss_import_url'] ?? NULL ), TRUE ) );
$form->add( new Number( 'block_rss_import_number', ( $this->configuration['block_rss_import_number'] ?? 5 ), TRUE ) );
$form->add( new Number( 'block_rss_import_cache', ( $this->configuration['block_rss_import_cache'] ?? 30 ), TRUE, array(), NULL, NULL, Member::loggedIn()->language()->addToStack('block_rss_import_cache_suffix') ) );
return $form;
}
@@ -80,7 +89,7 @@ class _Rss extends \IPS\Widget\StaticCache
* @param array $values Values from form
* @return array
*/
public function preConfig( $values )
public function preConfig( array $values ): array
{
$values['block_rss_import_url'] = (string) $values['block_rss_import_url'];
@@ -92,7 +101,7 @@ class _Rss extends \IPS\Widget\StaticCache
*
* @return string
*/
public function render()
public function render(): string
{
if ( ! isset( $this->configuration['block_rss_import_url'] ) )
{
@@ -101,9 +110,9 @@ class _Rss extends \IPS\Widget\StaticCache
$key = "cms_rss_import_" . md5( json_encode( $this->configuration ) );
if ( isset( \IPS\Data\Store::i()->$key ) )
if ( isset( Store::i()->$key ) )
{
$cache = \IPS\Data\Store::i()->$key;
$cache = Store::i()->$key;
if ( isset( $cache['time'] ) and isset( $cache['items'] ) and $cache['time'] > ( time() - ( $this->configuration['block_rss_import_cache'] * 60 ) ) )
{
@@ -114,7 +123,7 @@ class _Rss extends \IPS\Widget\StaticCache
/* Still here? Best grab the data then */
try
{
$request = \IPS\Http\Url::external( $this->configuration['block_rss_import_url'] )->request()->get();
$request = Url::external( $this->configuration['block_rss_import_url'] )->request()->get();
$i = 0;
$items = array();
@@ -126,9 +135,9 @@ class _Rss extends \IPS\Widget\StaticCache
{
$items[ $guid ] = array(
'title' => $article['title'],
'content' => \IPS\Text\Parser::parseStatic( $article['content'], TRUE, NULL, new \IPS\Member ),
'content' => Parser::parseStatic( $article['content'], NULL, new Member ),
'link' => (string) $article['link'],
'date' => ( $article['date'] instanceof \IPS\DateTime ) ? $article['date']->getTimestamp() : $article['date']
'date' => ( $article['date'] instanceof DateTime ) ? $article['date']->getTimestamp() : $article['date']
);
}
@@ -141,12 +150,12 @@ class _Rss extends \IPS\Widget\StaticCache
}
}
}
catch( \Exception $e )
catch( Exception $e )
{
$items = array();
}
\IPS\Data\Store::i()->$key = array( 'time' => time(), 'items' => $items );
Store::i()->$key = array( 'time' => time(), 'items' => $items );
return $this->output( $items, $this->configuration['block_rss_import_title'] );
}
+34 -27
View File
@@ -12,43 +12,50 @@
namespace IPS\cms\widgets;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use Exception;
use IPS\Db;
use IPS\File;
use IPS\Helpers\Form;
use IPS\Helpers\Form\Editor;
use IPS\Output;
use IPS\Widget\StaticCache;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* WYSIWYG Widget
*/
class _Wysiwyg extends \IPS\Widget\StaticCache
class Wysiwyg extends StaticCache
{
/**
* @brief Widget Key
*/
public $key = 'Wysiwyg';
public string $key = 'Wysiwyg';
/**
* @brief App
*/
public $app = 'cms';
public string $app = 'cms';
/**
* @brief Plugin
*/
public $plugin = '';
/**
* Specify widget configuration
*
* @param \IPS\Helpers\Form|NULL $form Form helper
* @return null|\IPS\Helpers\Form
* @param Form|NULL $form Form helper
* @return Form
*/
public function configuration( &$form=null )
public function configuration( Form &$form=null ): Form
{
$form = parent::configuration( $form );
$form->add( new \IPS\Helpers\Form\Editor( 'content', ( isset( $this->configuration['content'] ) ? $this->configuration['content'] : NULL ), FALSE, array(
$form->add( new Editor( 'content', ( $this->configuration['content'] ?? NULL ), FALSE, array(
'app' => $this->app,
'key' => 'Widgets',
'autoSaveKey' => 'widget-' . $this->uniqueKey,
@@ -63,25 +70,25 @@ class _Wysiwyg extends \IPS\Widget\StaticCache
*
* @return void
*/
public function delete()
public function delete() : void
{
foreach( \IPS\Db::i()->select( '*', 'core_attachments_map', array( array( 'location_key=? and id3=?', 'cms_Widgets', $this->uniqueKey ) ) ) as $map )
foreach( Db::i()->select( '*', 'core_attachments_map', array( array( 'location_key=? and id3=?', 'cms_Widgets', $this->uniqueKey ) ) ) as $map )
{
try
{
$attachment = \IPS\Db::i()->select( '*', 'core_attachments', array( 'attach_id=?', $map['attachment_id'] ) )->first();
$attachment = Db::i()->select( '*', 'core_attachments', array( 'attach_id=?', $map['attachment_id'] ) )->first();
\IPS\Db::i()->delete( 'core_attachments_map', array( array( 'attachment_id=?', $attachment['attach_id'] ) ) );
\IPS\Db::i()->delete( 'core_attachments', array( 'attach_id=?', $attachment['attach_id'] ) );
Db::i()->delete( 'core_attachments_map', array( array( 'attachment_id=?', $attachment['attach_id'] ) ) );
Db::i()->delete( 'core_attachments', array( 'attach_id=?', $attachment['attach_id'] ) );
\IPS\File::get( 'core_Attachment', $attachment['attach_location'] )->delete();
File::get( 'core_Attachment', $attachment['attach_location'] )->delete();
if ( $attachment['attach_thumb_location'] )
{
\IPS\File::get( 'core_Attachment', $attachment['attach_thumb_location'] )->delete();
File::get( 'core_Attachment', $attachment['attach_thumb_location'] )->delete();
}
}
catch ( \Exception $e ) { }
catch ( Exception $e ) { }
}
}
@@ -89,11 +96,11 @@ class _Wysiwyg extends \IPS\Widget\StaticCache
* Pre-save config method
*
* @param array $values Form values
* @return void
* @return array
*/
public function preConfig( $values=array() )
public function preConfig( array $values=array() ) : array
{
\IPS\File::claimAttachments( 'widget-' . $this->uniqueKey, 0, 0, $this->uniqueKey );
File::claimAttachments( 'widget-' . $this->uniqueKey, 0, 0, $this->uniqueKey );
return $values;
}
@@ -103,9 +110,9 @@ class _Wysiwyg extends \IPS\Widget\StaticCache
*
* @return string
*/
public function render()
public function render(): string
{
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'front_core.js', 'core' ) );
return $this->output( isset( $this->configuration['content'] ) ? $this->configuration['content'] : '' );
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, Output::i()->js( 'front_core.js', 'core' ) );
return $this->output( $this->configuration['content'] ?? '' );
}
}
+25 -20
View File
@@ -11,46 +11,51 @@
namespace IPS\cms\widgets;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use DomainException;
use IPS\Helpers\Form;
use IPS\Http\Url;
use IPS\Text\Parser;
use IPS\Widget\Builder;
use IPS\Widget\StaticCache;
use UnexpectedValueException;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* oembed Widget
*/
class _pagebuilderoembed extends \IPS\Widget\StaticCache implements \IPS\Widget\Builder
class pagebuilderoembed extends StaticCache implements Builder
{
/**
* @brief Widget Key
*/
public $key = 'pagebuilderoembed';
public string $key = 'pagebuilderoembed';
/**
* @brief App
*/
public $app = 'cms';
/**
* @brief Plugin
*/
public $plugin = '';
public string $app = 'cms';
/**
* Specify widget configuration
*
* @param null|\IPS\Helpers\Form $form Form object
* @return null|\IPS\Helpers\Form
* @param null|Form $form Form object
* @return Form
*/
public function configuration( &$form=null )
public function configuration( Form &$form=null ): Form
{
$form = parent::configuration( $form );
$form->add( new \IPS\Helpers\Form\Url( 'video_url', ( isset( $this->configuration['video_url'] ) )? $this->configuration['video_url'] : NULL, TRUE, array(), function( $url ) {
if ( \IPS\Text\Parser::embeddableMedia( \IPS\Http\Url::external( $url ) ) === NULL )
$form->add( new Form\Url( 'video_url', ( isset( $this->configuration['video_url'] ) )? $this->configuration['video_url'] : NULL, TRUE, array(), function( $url ) {
if ( Parser::embeddableMedia( Url::external( $url ) ) === NULL )
{
throw new \DomainException('video_cannot_embed');
throw new DomainException('video_cannot_embed');
}
} ) );
return $form;
@@ -62,7 +67,7 @@ class _pagebuilderoembed extends \IPS\Widget\StaticCache implements \IPS\Widget\
* @param array $values Values from form
* @return array
*/
public function preConfig( $values )
public function preConfig( array $values ): array
{
$values['video_url'] = (string) $values['video_url'];
return $values;
@@ -73,16 +78,16 @@ class _pagebuilderoembed extends \IPS\Widget\StaticCache implements \IPS\Widget\
*
* @return string
*/
public function render()
public function render(): string
{
try
{
if ( isset( $this->configuration['video_url'] ) AND $embed = \IPS\Text\Parser::embeddableMedia( \IPS\Http\Url::external( $this->configuration['video_url'] ) ) )
if ( isset( $this->configuration['video_url'] ) AND $embed = Parser::embeddableMedia( Url::external( $this->configuration['video_url'] ) ) )
{
return $this->output( $embed );
}
}
catch( \UnexpectedValueException $e ){}
catch( UnexpectedValueException $e ){}
return '';
}
+17 -15
View File
@@ -11,43 +11,45 @@
namespace IPS\cms\widgets;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Helpers\Form;
use IPS\Helpers\Form\TextArea;
use IPS\Widget\Builder;
use IPS\Widget\StaticCache;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* pagebuildertext Widget
*/
class _pagebuildertext extends \IPS\Widget\StaticCache implements \IPS\Widget\Builder
class pagebuildertext extends StaticCache implements Builder
{
/**
* @brief Widget Key
*/
public $key = 'pagebuildertext';
public string $key = 'pagebuildertext';
/**
* @brief App
*/
public $app = 'cms';
/**
* @brief Plugin
*/
public $plugin = '';
public string $app = 'cms';
/**
* Specify widget configuration
*
* @param null|\IPS\Helpers\Form $form Form object
* @return null|\IPS\Helpers\Form
* @param null|Form $form Form object
* @return Form
*/
public function configuration( &$form=null )
public function configuration( Form &$form=null ): Form
{
$form = parent::configuration( $form );
$form->add( new \IPS\Helpers\Form\TextArea( 'pagebuilder_text', ( isset( $this->configuration['pagebuilder_text'] ) ? $this->configuration['pagebuilder_text'] : '' ), FALSE, array( 'rows' => 10 ) ) );
$form->add( new TextArea( 'pagebuilder_text', ( $this->configuration['pagebuilder_text'] ?? '' ), FALSE, array( 'rows' => 10 ) ) );
return $form;
}
@@ -56,7 +58,7 @@ class _pagebuildertext extends \IPS\Widget\StaticCache implements \IPS\Widget\Bu
*
* @return string
*/
public function render()
public function render(): string
{
if ( ! empty( $this->configuration['pagebuilder_text'] ) )
{
+35 -25
View File
@@ -11,39 +11,49 @@
namespace IPS\cms\widgets;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use Exception;
use IPS\File;
use IPS\Helpers\Form;
use IPS\Helpers\Form\Number;
use IPS\Helpers\Form\Stack;
use IPS\Helpers\Form\Upload;
use IPS\Helpers\Form\YesNo;
use IPS\Widget\Builder;
use IPS\Widget\StaticCache;
use function count;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* pagebuilderupload Widget
*/
class _pagebuilderupload extends \IPS\Widget\StaticCache implements \IPS\Widget\Builder
class pagebuilderupload extends StaticCache implements Builder
{
/**
* @brief Widget Key
*/
public $key = 'pagebuilderupload';
public string $key = 'pagebuilderupload';
/**
* @brief App
*/
public $app = 'cms';
public string $app = 'cms';
/**
* @brief Plugin
*/
public $plugin = '';
/**
* Specify widget configuration
*
* @param null|\IPS\Helpers\Form $form Form object
* @return null|\IPS\Helpers\Form
* @param null|Form $form Form object
* @return Form
*/
public function configuration( &$form=null )
public function configuration( Form &$form=null ): Form
{
$form = parent::configuration( $form );
@@ -55,7 +65,7 @@ class _pagebuilderupload extends \IPS\Widget\StaticCache implements \IPS\Widget\
{
foreach( explode( ',', $this->configuration['pagebuilderupload_upload'] ) as $img )
{
$images[] = \IPS\File::get( 'core_Attachment', $img );
$images[] = File::get( 'core_Attachment', $img );
}
}
@@ -75,12 +85,12 @@ class _pagebuilderupload extends \IPS\Widget\StaticCache implements \IPS\Widget\
}
}
$form->add( new \IPS\Helpers\Form\Upload( 'pagebuilderupload_upload', $images, FALSE, array( 'multiple' => true, 'storageExtension' => 'core_Attachment', 'allowStockPhotos' => TRUE, 'image' => true ) ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'pagebuilderupload_slideshow', ( isset( $this->configuration['pagebuilderupload_slideshow'] ) ? $this->configuration['pagebuilderupload_slideshow'] : FALSE ) ) );
$form->add( new \IPS\Helpers\Form\Stack( 'pagebuilderupload_captions', $captions, FALSE, array( 'stackFieldType' => 'Text' ) ) );
$form->add( new \IPS\Helpers\Form\Stack( 'pagebuilderupload_urls', $urls, FALSE, array( 'stackFieldType' => 'Url' ) ) );
$form->add( new Upload( 'pagebuilderupload_upload', $images, FALSE, array( 'multiple' => true, 'storageExtension' => 'core_Attachment', 'allowStockPhotos' => TRUE, 'image' => true ) ) );
$form->add( new YesNo( 'pagebuilderupload_slideshow', ( $this->configuration['pagebuilderupload_slideshow'] ?? FALSE ) ) );
$form->add( new Stack( 'pagebuilderupload_captions', $captions, FALSE, array( 'stackFieldType' => 'Text' ) ) );
$form->add( new Stack( 'pagebuilderupload_urls', $urls, FALSE, array( 'stackFieldType' => 'Url' ) ) );
$form->add( new \IPS\Helpers\Form\Number( 'pagebuilderupload_height', ( isset( $this->configuration['pagebuilderupload_height'] ) ? $this->configuration['pagebuilderupload_height'] : 300 ), FALSE, array( 'unlimited' => 0 ) ) );
$form->add( new Number( 'pagebuilderupload_height', ( $this->configuration['pagebuilderupload_height'] ?? 300 ), FALSE, array( 'unlimited' => 0 ) ) );
return $form;
}
@@ -89,15 +99,15 @@ class _pagebuilderupload extends \IPS\Widget\StaticCache implements \IPS\Widget\
*
* @return void
*/
public function delete()
public function delete() : void
{
foreach( explode( ',', $this->configuration['pagebuilderupload_upload'] ) as $img )
{
try
{
\IPS\File::get( 'core_Attachment', $img )->delete();
File::get( 'core_Attachment', $img )->delete();
}
catch( \Exception $e ) { }
catch( Exception $e ) { }
}
}
@@ -107,7 +117,7 @@ class _pagebuilderupload extends \IPS\Widget\StaticCache implements \IPS\Widget\
* @param array $values Values from form
* @return array
*/
public function preConfig( $values )
public function preConfig( array $values ): array
{
$images = array();
$urls = array();
@@ -132,7 +142,7 @@ class _pagebuilderupload extends \IPS\Widget\StaticCache implements \IPS\Widget\
*
* @return string
*/
public function render()
public function render() : string
{
$images = array();
$captions = ( isset( $this->configuration['pagebuilderupload_captions'] ) ) ? $this->configuration['pagebuilderupload_captions'] : array();
@@ -144,10 +154,10 @@ class _pagebuilderupload extends \IPS\Widget\StaticCache implements \IPS\Widget\
{
foreach( explode( ',', $this->configuration['pagebuilderupload_upload'] ) as $img )
{
$images[] = (string) \IPS\File::get( 'core_Attachment', $img )->url;
$images[] = (string) File::get( 'core_Attachment', $img )->url;
}
return $this->output( ( \count( $images ) === 1 ? $images[0] : $images ), $captions, $urls, $autoPlay, $maxHeight );
return $this->output( ( count( $images ) === 1 ? $images[0] : $images ), $captions, $urls, $autoPlay, $maxHeight );
}
return '';