Version 5.0.0 beta 1
This commit is contained in:
1 parent
25ddeb65d6
commit
15c7beabc5
6736 files changed
+627902
-497943
No files matched your search
@@ -1,4 +1,6 @@
|
||||
<?php
|
||||
|
||||
|
||||
/**
|
||||
* @brief Fields Model
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
@@ -12,54 +14,65 @@
|
||||
namespace IPS\cms\modules\admin\databases;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\cms\Databases;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Member;
|
||||
use IPS\Node\Controller;
|
||||
use IPS\Node\Model;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
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
|
||||
*/
|
||||
class _categories extends \IPS\Node\Controller
|
||||
class categories extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Node Class
|
||||
*/
|
||||
protected $nodeClass = '\IPS\cms\Categories';
|
||||
protected string $nodeClass = '\IPS\cms\Categories';
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'databases_use' );
|
||||
Dispatcher::i()->checkAcpPermission( 'databases_use' );
|
||||
|
||||
/* This controller can not be accessed without a database ID */
|
||||
if( !\IPS\Request::i()->database_id )
|
||||
if( !Request::i()->database_id )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2S390/1', 404, '' );
|
||||
Output::i()->error( 'node_error', '2S390/1', 404, '' );
|
||||
}
|
||||
|
||||
$this->url = $this->url->setQueryString( array( 'database_id' => \IPS\Request::i()->database_id ) );
|
||||
$this->url = $this->url->setQueryString( array( 'database_id' => Request::i()->database_id ) );
|
||||
|
||||
/* Assign the correct nodeClass so contentItem is specified */
|
||||
$this->nodeClass = '\IPS\cms\Categories' . \IPS\Request::i()->database_id;
|
||||
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'categories_manage' );
|
||||
$this->nodeClass = '\IPS\cms\Categories' . Request::i()->database_id;
|
||||
|
||||
Dispatcher::i()->checkAcpPermission( 'categories_manage' );
|
||||
|
||||
/* @var Model $nodeClass */
|
||||
$nodeClass = $this->nodeClass;
|
||||
|
||||
$childLang = \IPS\Member::loggedIn()->language()->addToStack( $nodeClass::$nodeTitle . '_add_child' );
|
||||
$nodeClass::$nodeTitle = \IPS\Member::loggedIn()->language()->addToStack('content_cat_db_title', FALSE, array( 'sprintf' => array( \IPS\cms\Databases::load( \IPS\Request::i()->database_id )->_title ) ) );
|
||||
\IPS\Member::loggedIn()->language()->words[ $nodeClass::$nodeTitle . '_add_child' ] = $childLang;
|
||||
$childLang = Member::loggedIn()->language()->addToStack( $nodeClass::$nodeTitle . '_add_child' );
|
||||
$nodeClass::$nodeTitle = Member::loggedIn()->language()->addToStack('content_cat_db_title', FALSE, array( 'sprintf' => array( Databases::load( Request::i()->database_id )->_title ) ) );
|
||||
Member::loggedIn()->language()->words[ $nodeClass::$nodeTitle . '_add_child' ] = $childLang;
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -68,14 +81,15 @@ class _categories extends \IPS\Node\Controller
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function _getRoots()
|
||||
public function _getRoots(): array
|
||||
{
|
||||
/* @var Model $nodeClass */
|
||||
$nodeClass = $this->nodeClass;
|
||||
$rows = array();
|
||||
|
||||
foreach( $nodeClass::roots( NULL ) as $node )
|
||||
{
|
||||
if ( $node->database_id == \IPS\Request::i()->database_id )
|
||||
if ( $node->database_id == Request::i()->database_id )
|
||||
{
|
||||
$rows[ $node->_id ] = $this->_getRow( $node );
|
||||
}
|
||||
@@ -91,8 +105,9 @@ class _categories extends \IPS\Node\Controller
|
||||
* @return void
|
||||
* @note Pages needs to readjust category_full_path values when a category is moved to a different category
|
||||
*/
|
||||
protected function _afterReorder( $order )
|
||||
protected function _afterReorder( array $order ) : void
|
||||
{
|
||||
/* @var Model $categoryClass */
|
||||
$categoryClass = $this->nodeClass;
|
||||
|
||||
foreach( $order as $parent => $nodes )
|
||||
@@ -103,6 +118,6 @@ class _categories extends \IPS\Node\Controller
|
||||
}
|
||||
}
|
||||
|
||||
return parent::_afterReorder( $order );
|
||||
parent::_afterReorder( $order );
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -12,40 +12,62 @@
|
||||
namespace IPS\cms\modules\admin\databases;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\cms\Databases;
|
||||
use IPS\cms\Fields as FieldsClass;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\Checkbox;
|
||||
use IPS\Helpers\Form\Matrix;
|
||||
use IPS\Helpers\Form\Node;
|
||||
use IPS\Helpers\Tree\Tree;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\Member\Group;
|
||||
use IPS\Node\Controller;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
use IPS\Session;
|
||||
use IPS\Theme;
|
||||
use OutOfRangeException;
|
||||
use function defined;
|
||||
use function in_array;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* fields
|
||||
*/
|
||||
class _fields extends \IPS\Node\Controller
|
||||
class fields extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Node Class
|
||||
*/
|
||||
protected $nodeClass = '\IPS\cms\Fields';
|
||||
protected string $nodeClass = '\IPS\cms\Fields';
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
$this->url = $this->url->setQueryString( array( 'database_id' => \IPS\Request::i()->database_id ) );
|
||||
$this->url = $this->url->setQueryString( array( 'database_id' => Request::i()->database_id ) );
|
||||
|
||||
$this->nodeClass = '\IPS\cms\Fields' . \IPS\Request::i()->database_id;
|
||||
$this->nodeClass = '\IPS\cms\Fields' . Request::i()->database_id;
|
||||
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'databases_use' );
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'cms_fields_manage' );
|
||||
Dispatcher::i()->checkAcpPermission( 'databases_use' );
|
||||
Dispatcher::i()->checkAcpPermission( 'cms_fields_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -54,42 +76,43 @@ class _fields extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
protected function manage() : void
|
||||
{
|
||||
/* If we lose the database id because of a log in, do something more useful than an uncaught exception */
|
||||
if ( ! isset( \IPS\Request::i()->database_id ) )
|
||||
if ( ! isset( Request::i()->database_id ) )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=cms&module=databases" ) );
|
||||
Output::i()->redirect( Url::internal( "app=cms&module=databases" ) );
|
||||
}
|
||||
|
||||
parent::manage();
|
||||
|
||||
$url = \IPS\Http\Url::internal( "app=cms&module=databases&controller=fields&database_id=" . \IPS\Request::i()->database_id );
|
||||
|
||||
$class = '\IPS\cms\Fields' . \IPS\Request::i()->database_id;
|
||||
$url = Url::internal( "app=cms&module=databases&controller=fields&database_id=" . Request::i()->database_id );
|
||||
|
||||
/* @var FieldsClass $class */
|
||||
$class = '\IPS\cms\Fields' . Request::i()->database_id;
|
||||
|
||||
/* Build fixed fields */
|
||||
$fixed = array_merge( array( 'record_publish_date' => array(), 'record_expiry_date' => array(), 'record_allow_comments' => array(), 'record_comment_cutoff' => array(), 'record_image' => array() ), $class::fixedFieldPermissions() );
|
||||
|
||||
/* Fixed fields */
|
||||
$fixedFields = new \IPS\Helpers\Tree\Tree(
|
||||
$fixedFields = new Tree(
|
||||
$url,
|
||||
\IPS\Member::loggedIn()->language()->addToStack('content_fields_fixed_title'),
|
||||
Member::loggedIn()->language()->addToStack('content_fields_fixed_title'),
|
||||
function() use ( $fixed, $url )
|
||||
{
|
||||
$rows = array();
|
||||
|
||||
foreach( $fixed as $field => $data )
|
||||
{
|
||||
$description = ( $field === 'record_publish_date' ) ? \IPS\Member::loggedIn()->language()->addToStack( 'content_fields_fixed_record_publish_date_desc' ) : NULL;
|
||||
$rows[ $field ] = \IPS\Theme::i()->getTemplate( 'trees', 'core' )->row( $url, $field, \IPS\Member::loggedIn()->language()->addToStack( 'content_fields_fixed_'. $field ), FALSE, array(
|
||||
$description = ( $field === 'record_publish_date' ) ? Member::loggedIn()->language()->addToStack( 'content_fields_fixed_record_publish_date_desc' ) : NULL;
|
||||
$rows[ $field ] = Theme::i()->getTemplate( 'trees', 'core' )->row( $url, $field, Member::loggedIn()->language()->addToStack( 'content_fields_fixed_'. $field ), FALSE, array(
|
||||
'permission' => array(
|
||||
'icon' => 'lock',
|
||||
'title' => 'permissions',
|
||||
'link' => $url->setQueryString( array( 'field' => $field, 'do' => 'fixedPermissions' ) ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack( 'content_fields_fixed_'. $field ) )
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => Member::loggedIn()->language()->addToStack( 'content_fields_fixed_'. $field ) )
|
||||
)
|
||||
), $description, NULL, NULL, NULL, ( empty( $data['visible'] ) ? FALSE : TRUE ) );
|
||||
), $description, NULL, NULL, NULL, !empty($data['visible']));
|
||||
}
|
||||
|
||||
return $rows;
|
||||
@@ -103,9 +126,9 @@ class _fields extends \IPS\Node\Controller
|
||||
TRUE
|
||||
);
|
||||
|
||||
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'databases' )->fieldsWrapper( $fixedFields );
|
||||
Output::i()->output .= Theme::i()->getTemplate( 'databases' )->fieldsWrapper( $fixedFields );
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('content_database_field_area', FALSE, array( 'sprintf' => array( \IPS\cms\Databases::load( \IPS\Request::i()->database_id)->_title ) ) );
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('content_database_field_area', FALSE, array( 'sprintf' => array( Databases::load( Request::i()->database_id)->_title ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -113,14 +136,15 @@ class _fields extends \IPS\Node\Controller
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function _getRoots()
|
||||
public function _getRoots(): array
|
||||
{
|
||||
/* @var FieldsClass $nodeClass */
|
||||
$nodeClass = $this->nodeClass;
|
||||
$rows = array();
|
||||
|
||||
foreach( $nodeClass::roots( NULL ) as $node )
|
||||
{
|
||||
if ( $node->database_id == \IPS\Request::i()->database_id )
|
||||
if ( $node->database_id == Request::i()->database_id )
|
||||
{
|
||||
$rows[ $node->_id ] = $this->_getRow( $node );
|
||||
}
|
||||
@@ -134,22 +158,23 @@ class _fields extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function enableToggle()
|
||||
public function enableToggle() : void
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
/* @var FieldsClass $class */
|
||||
$class = '\IPS\cms\Fields' . Request::i()->database_id;
|
||||
|
||||
$class = '\IPS\cms\Fields' . \IPS\Request::i()->database_id;
|
||||
|
||||
$class::setFixedFieldVisibility( \IPS\Request::i()->id, (boolean) \IPS\Request::i()->status );
|
||||
$class::setFixedFieldVisibility( Request::i()->id, (boolean) Request::i()->status );
|
||||
|
||||
/* Redirect */
|
||||
if ( \IPS\Request::i()->status )
|
||||
if ( Request::i()->status )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=cms&module=databases&controller=fields&database_id=" . \IPS\Request::i()->database_id . '&do=fixedPermissions&field=' . \IPS\Request::i()->id ) );
|
||||
Output::i()->redirect( Url::internal( "app=cms&module=databases&controller=fields&database_id=" . Request::i()->database_id . '&do=fixedPermissions&field=' . Request::i()->id ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=cms&module=databases&controller=fields&database_id=" . \IPS\Request::i()->database_id ), 'saved' );
|
||||
Output::i()->redirect( Url::internal( "app=cms&module=databases&controller=fields&database_id=" . Request::i()->database_id ), 'saved' );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,16 +183,17 @@ class _fields extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setAsTitle()
|
||||
public function setAsTitle() : void
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
$class = '\IPS\cms\Fields' . \IPS\Request::i()->database_id;
|
||||
$database = \IPS\cms\Databases::load( \IPS\Request::i()->database_id );
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
/* @var FieldsClass $class */
|
||||
$class = '\IPS\cms\Fields' . Request::i()->database_id;
|
||||
$database = Databases::load( Request::i()->database_id );
|
||||
|
||||
try
|
||||
{
|
||||
$field = $class::load( \IPS\Request::i()->id );
|
||||
$field = $class::load( Request::i()->id );
|
||||
|
||||
if ( $field->canBeTitleField() )
|
||||
{
|
||||
@@ -175,11 +201,11 @@ class _fields extends \IPS\Node\Controller
|
||||
$database->save();
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=cms&module=databases&controller=fields&database_id=" . \IPS\Request::i()->database_id ), 'saved' );
|
||||
Output::i()->redirect( Url::internal( "app=cms&module=databases&controller=fields&database_id=" . Request::i()->database_id ), 'saved' );
|
||||
}
|
||||
catch( \OutOfRangeException $ex )
|
||||
catch( OutOfRangeException $ex )
|
||||
{
|
||||
\IPS\Output::i()->error( 'cms_cannot_find_field', '2T255/1', 403, '' );
|
||||
Output::i()->error( 'cms_cannot_find_field', '2T255/1', 403, '' );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,16 +214,17 @@ class _fields extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setAsContent()
|
||||
public function setAsContent() : void
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
$class = '\IPS\cms\Fields' . \IPS\Request::i()->database_id;
|
||||
$database = \IPS\cms\Databases::load( \IPS\Request::i()->database_id );
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
/* @var FieldsClass $class */
|
||||
$class = '\IPS\cms\Fields' . Request::i()->database_id;
|
||||
$database = Databases::load( Request::i()->database_id );
|
||||
|
||||
try
|
||||
{
|
||||
$field = $class::load( \IPS\Request::i()->id );
|
||||
$field = $class::load( Request::i()->id );
|
||||
|
||||
if ( $field->canBeContentField() )
|
||||
{
|
||||
@@ -205,11 +232,11 @@ class _fields extends \IPS\Node\Controller
|
||||
$database->save();
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=cms&module=databases&controller=fields&database_id=" . \IPS\Request::i()->database_id ), 'saved' );
|
||||
Output::i()->redirect( Url::internal( "app=cms&module=databases&controller=fields&database_id=" . Request::i()->database_id ), 'saved' );
|
||||
}
|
||||
catch( \OutOfRangeException $ex )
|
||||
catch( OutOfRangeException $ex )
|
||||
{
|
||||
\IPS\Output::i()->error( 'cms_cannot_find_field', '2T255/2', 403, '' );
|
||||
Output::i()->error( 'cms_cannot_find_field', '2T255/2', 403, '' );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,10 +245,11 @@ class _fields extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function fixedPermissions()
|
||||
public function fixedPermissions() : void
|
||||
{
|
||||
$class = '\IPS\cms\Fields' . \IPS\Request::i()->database_id;
|
||||
$perms = $class::fixedFieldPermissions( \IPS\Request::i()->field );
|
||||
/* @var FieldsClass $class */
|
||||
$class = '\IPS\cms\Fields' . Request::i()->database_id;
|
||||
$perms = $class::fixedFieldPermissions( Request::i()->field );
|
||||
|
||||
$permMap = array( 'view' => 'view', 'edit' => 2, 'add' => 3 );
|
||||
|
||||
@@ -234,7 +262,7 @@ class _fields extends \IPS\Node\Controller
|
||||
}
|
||||
|
||||
/* Build Matrix */
|
||||
$matrix = new \IPS\Helpers\Form\Matrix;
|
||||
$matrix = new Matrix;
|
||||
$matrix->manageable = FALSE;
|
||||
$matrix->langPrefix = 'content_perm_fixed_fields__';
|
||||
$matrix->columns = array(
|
||||
@@ -248,14 +276,14 @@ class _fields extends \IPS\Node\Controller
|
||||
$matrix->columns[ $k ] = function( $key, $value, $data ) use ( $perms, $k, $v )
|
||||
{
|
||||
$groupId = mb_substr( $key, 0, -( 2 + mb_strlen( $k ) ) );
|
||||
return new \IPS\Helpers\Form\Checkbox( $key, isset( $perms[ "perm_{$v}" ] ) and ( $perms[ "perm_{$v}" ] === '*' or \in_array( $groupId, explode( ',', $perms[ "perm_{$v}" ] ) ) ) );
|
||||
return new Checkbox( $key, isset( $perms[ "perm_{$v}" ] ) and ( $perms[ "perm_{$v}" ] === '*' or in_array( $groupId, explode( ',', $perms[ "perm_{$v}" ] ) ) ) );
|
||||
};
|
||||
$matrix->checkAlls[ $k ] = ( $perms[ "perm_{$v}" ] === '*' );
|
||||
}
|
||||
$matrix->checkAllRows = TRUE;
|
||||
|
||||
$rows = array();
|
||||
foreach ( \IPS\Member\Group::groups() as $group )
|
||||
foreach ( Group::groups() as $group )
|
||||
{
|
||||
$rows[ $group->g_id ] = array(
|
||||
'label' => $group->name,
|
||||
@@ -273,7 +301,7 @@ class _fields extends \IPS\Node\Controller
|
||||
/* Check for "all" checkboxes */
|
||||
foreach ( $permMap as $k => $v )
|
||||
{
|
||||
if ( isset( \IPS\Request::i()->__all[ $k ] ) )
|
||||
if ( isset( Request::i()->__all[ $k ] ) )
|
||||
{
|
||||
$_perms[ $v ] = '*';
|
||||
}
|
||||
@@ -288,7 +316,7 @@ class _fields extends \IPS\Node\Controller
|
||||
{
|
||||
foreach ( $permMap as $k => $v )
|
||||
{
|
||||
if ( isset( $perms[ $k ] ) and $perms[ $k ] and \is_array( $_perms[ $v ] ) )
|
||||
if ( isset( $perms[ $k ] ) and $perms[ $k ] and is_array( $_perms[ $v ] ) )
|
||||
{
|
||||
$_perms[ $v ][] = $group;
|
||||
}
|
||||
@@ -298,18 +326,89 @@ class _fields extends \IPS\Node\Controller
|
||||
/* Finalise */
|
||||
foreach ( $_perms as $k => $v )
|
||||
{
|
||||
$save[ "perm_{$k}" ] = \is_array( $v ) ? implode( ',', $v ) : $v;
|
||||
$save[ "perm_{$k}" ] = is_array( $v ) ? implode( ',', $v ) : $v;
|
||||
}
|
||||
|
||||
$class::setFixedFieldPermissions( \IPS\Request::i()->field, $save );
|
||||
$class::setFixedFieldPermissions( Request::i()->field, $save );
|
||||
|
||||
/* Redirect */
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=cms&module=databases&controller=fields&database_id=" . \IPS\Request::i()->database_id ), 'saved' );
|
||||
Output::i()->redirect( Url::internal( "app=cms&module=databases&controller=fields&database_id=" . Request::i()->database_id ), 'saved' );
|
||||
}
|
||||
|
||||
/* Display */
|
||||
\IPS\Output::i()->output .= $matrix;
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('content_database_manage_fields');
|
||||
|
||||
Output::i()->output .= $matrix;
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('content_database_manage_fields');
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage field toggles
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function toggles() : void
|
||||
{
|
||||
/* @var FieldsClass $class */
|
||||
$class = '\IPS\cms\Fields' . Request::i()->database_id;
|
||||
$database = Databases::load( Request::i()->database_id );
|
||||
try
|
||||
{
|
||||
$field = $class::load( Request::i()->id );
|
||||
if( !in_array( $field->type, $class::$canUseTogglesFields ) )
|
||||
{
|
||||
Output::i()->error( 'This field type cannot use toggles', 'CMSFT/2' );
|
||||
}
|
||||
}
|
||||
catch( OutOfRangeException $e )
|
||||
{
|
||||
Output::i()->error( 'node_error', '1CMSFT/1', 404 );
|
||||
}
|
||||
|
||||
$form = new Form;
|
||||
$form->class = 'ipsPad';
|
||||
|
||||
$form->addMessage( 'cms_fields_toggles_info', 'ipsMessage ipsMessage--info' );
|
||||
if( $field->type == 'YesNo' OR $field->type == 'Checkbox' )
|
||||
{
|
||||
$options = array(
|
||||
'togglesOn' => Member::loggedIn()->language()->addToStack( 'field_toggles_on' ),
|
||||
'togglesOff' => Member::loggedIn()->language()->addToStack( 'field_toggles_off' )
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$options = $field->extra;
|
||||
}
|
||||
|
||||
$currentToggles = ( $field->toggles ? json_decode( $field->toggles, true ) : array() );
|
||||
foreach( $options as $k => $v )
|
||||
{
|
||||
$formField = new Node( 'field_field_toggles_' . $k, ( $currentToggles[$k] ?? null ), false, array(
|
||||
'class' => $class,
|
||||
'multiple' => true,
|
||||
'disabledIds' => array( $field->id, $database->field_title, $database->field_content )
|
||||
) );
|
||||
$formField->label = $v;
|
||||
$form->add( $formField );
|
||||
}
|
||||
|
||||
if( $values = $form->values() )
|
||||
{
|
||||
$toggles = array();
|
||||
foreach( $options as $k => $v )
|
||||
{
|
||||
$key = 'field_field_toggles_' . $k;
|
||||
if( isset( $values[$key] ) AND is_array( $values[$key] ) AND count( $values[$key] ) )
|
||||
{
|
||||
$toggles[$k] = array_keys( $values[$key] );
|
||||
}
|
||||
}
|
||||
|
||||
$field->toggles = json_encode( $toggles );
|
||||
$field->save();
|
||||
|
||||
Output::i()->redirect( $this->url );
|
||||
}
|
||||
|
||||
Output::i()->output = (string) $form;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @brief Records Model
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
@@ -12,33 +13,63 @@
|
||||
namespace IPS\cms\modules\admin\databases;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DomainException;
|
||||
use Exception;
|
||||
use IPS\cms\Categories as CategoriesClass;
|
||||
use IPS\cms\Databases;
|
||||
use IPS\cms\Fields as FieldsClass;
|
||||
use IPS\cms\Records as RecordsClass;
|
||||
use IPS\Data\Cache;
|
||||
use IPS\DateTime;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\File;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\Node;
|
||||
use IPS\Helpers\Form\Radio;
|
||||
use IPS\Helpers\Table\Db;
|
||||
use IPS\Http\Url;
|
||||
use IPS\IPS;
|
||||
use IPS\Member;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
use IPS\Session;
|
||||
use IPS\Theme;
|
||||
use LogicException;
|
||||
use OutOfRangeException;
|
||||
use function defined;
|
||||
use function in_array;
|
||||
use const IPS\Helpers\Table\SEARCH_NODE;
|
||||
use const IPS\Helpers\Table\SEARCH_SELECT;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* records
|
||||
*/
|
||||
class _records extends \IPS\Dispatcher\Controller
|
||||
class records extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
$this->url = $this->url->setQueryString( array( 'database_id' => \IPS\Request::i()->database_id ) );
|
||||
$this->url = $this->url->setQueryString( array( 'database_id' => Request::i()->database_id ) );
|
||||
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'databases_use' );
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'records_manage' );
|
||||
Dispatcher::i()->checkAcpPermission( 'databases_use' );
|
||||
Dispatcher::i()->checkAcpPermission( 'records_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -47,26 +78,26 @@ class _records extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
protected function manage() : void
|
||||
{
|
||||
/* There may be no database ID if the admin only has permission to view records and not the database list itself */
|
||||
if ( !\IPS\Request::i()->database_id )
|
||||
if ( !Request::i()->database_id )
|
||||
{
|
||||
foreach ( \IPS\cms\Databases::databases() as $database )
|
||||
foreach ( Databases::databases() as $database )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=cms&module=databases&controller=records&do=manage&database_id=' . $database->_id ) );
|
||||
Output::i()->redirect( Url::internal( 'app=cms&module=databases&controller=records&do=manage&database_id=' . $database->_id ) );
|
||||
}
|
||||
}
|
||||
|
||||
$database = \IPS\cms\Databases::load( \IPS\Request::i()->database_id );
|
||||
$title = \IPS\Member::loggedIn()->language()->addToStack('content_record_db_title', TRUE, array( 'sprintf' => array( $database->_title ) ) );
|
||||
$database = Databases::load( Request::i()->database_id );
|
||||
$title = Member::loggedIn()->language()->addToStack('content_record_db_title', TRUE, array( 'sprintf' => array( $database->_title ) ) );
|
||||
|
||||
/* Create the table */
|
||||
$table = new \IPS\Helpers\Table\Db( 'cms_custom_database_' . \IPS\Request::i()->database_id, \IPS\Http\Url::internal( 'app=cms&module=databases&controller=records' ) );
|
||||
$table = new Db( 'cms_custom_database_' . Request::i()->database_id, Url::internal( 'app=cms&module=databases&controller=records' ) );
|
||||
$table->langPrefix = 'content_db_table_';
|
||||
$table->title = $title;
|
||||
$table->quickSearch = 'field_' . $database->field_title;
|
||||
$table->baseUrl = $table->baseUrl->setQueryString( array( 'database_id' => \IPS\Request::i()->database_id ) );
|
||||
$table->baseUrl = $table->baseUrl->setQueryString( array( 'database_id' => Request::i()->database_id ) );
|
||||
|
||||
/* Only specify these if we are not re-ordering via the table headers, which are set in the Table contructor */
|
||||
if ( ! $table->sortBy )
|
||||
@@ -105,16 +136,16 @@ class _records extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
|
||||
/* Add title header */
|
||||
\IPS\Member::loggedIn()->language()->words['content_db_table_field_' . $database->field_title ] = \IPS\Member::loggedIn()->language()->addToStack( 'content_db_table_title' );
|
||||
Member::loggedIn()->language()->words['content_db_table_field_' . $database->field_title ] = Member::loggedIn()->language()->addToStack( 'content_db_table_title' );
|
||||
|
||||
$table->advancedSearch = array(
|
||||
'category_id' => array( \IPS\Helpers\Table\SEARCH_NODE, array(
|
||||
'category_id' => array( SEARCH_NODE, array(
|
||||
'class' => '\IPS\cms\Categories' . $database->id,
|
||||
'disabled' => false,
|
||||
'zeroVal' => 'content_db_table_as_no_cat'
|
||||
),
|
||||
),
|
||||
'record_comments'=> array( \IPS\Helpers\Table\SEARCH_SELECT, array( 'options' => array(
|
||||
'record_comments'=> array( SEARCH_SELECT, array( 'options' => array(
|
||||
'null' => 'content_db_table_as_comments_null',
|
||||
1 => 'content_db_table_as_comments_yes',
|
||||
2 => 'content_db_table_as_comments_no'
|
||||
@@ -125,21 +156,21 @@ class _records extends \IPS\Dispatcher\Controller
|
||||
/* Buttons */
|
||||
if ( $database->use_categories )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['actions']['add'] = array(
|
||||
Output::i()->sidebar['actions']['add'] = array(
|
||||
'primary' => true,
|
||||
'title' => 'add',
|
||||
'icon' => 'plus',
|
||||
'link' => \IPS\Http\Url::internal( 'app=cms&module=databases&controller=records&do=select&database_id=' . \IPS\Request::i()->database_id ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('database_select_category' ) )
|
||||
'link' => Url::internal( 'app=cms&module=databases&controller=records&do=select&database_id=' . Request::i()->database_id ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => Member::loggedIn()->language()->addToStack('database_select_category' ), 'ipsDialog-size' => 'narrow' )
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->sidebar['actions']['add'] = array(
|
||||
Output::i()->sidebar['actions']['add'] = array(
|
||||
'primary' => true,
|
||||
'title' => 'add',
|
||||
'icon' => 'plus',
|
||||
'link' => \IPS\Http\Url::internal( 'app=cms&module=databases&controller=records&do=form&database_id=' . \IPS\Request::i()->database_id )
|
||||
'link' => Url::internal( 'app=cms&module=databases&controller=records&do=form&database_id=' . Request::i()->database_id )
|
||||
);
|
||||
}
|
||||
|
||||
@@ -148,12 +179,12 @@ class _records extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
$return = array();
|
||||
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'cms', 'databases', 'records_edit' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'cms', 'databases', 'records_edit' ) )
|
||||
{
|
||||
$return['edit'] = array(
|
||||
'title' => 'edit',
|
||||
'icon' => 'pencil',
|
||||
'link' => \IPS\Http\Url::internal('app=cms&module=databases&controller=records&database_id=' . \IPS\Request::i()->database_id . '&id=' . $row['primary_id_field'] . '&do=form'),
|
||||
'link' => Url::internal('app=cms&module=databases&controller=records&database_id=' . Request::i()->database_id . '&id=' . $row['primary_id_field'] . '&do=form'),
|
||||
'data' => array()
|
||||
);
|
||||
}
|
||||
@@ -161,16 +192,16 @@ class _records extends \IPS\Dispatcher\Controller
|
||||
$return['move'] = array(
|
||||
'title' => 'move',
|
||||
'icon' => 'arrow-right',
|
||||
'link' => \IPS\Http\Url::internal( 'app=cms&module=databases&controller=records&database_id=' . \IPS\Request::i()->database_id . '&do=select&move=' . $row['primary_id_field'] ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('database_select_category' ) )
|
||||
'link' => Url::internal( 'app=cms&module=databases&controller=records&database_id=' . Request::i()->database_id . '&do=select&move=' . $row['primary_id_field'] ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => Member::loggedIn()->language()->addToStack('database_select_category' ) )
|
||||
);
|
||||
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'cms', 'databases', 'records_delete' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'cms', 'databases', 'records_delete' ) )
|
||||
{
|
||||
$return['delete'] = array(
|
||||
'title' => 'delete',
|
||||
'icon' => 'times-circle',
|
||||
'link' => \IPS\Http\Url::internal( 'app=cms&module=databases&controller=records&database_id=' . \IPS\Request::i()->database_id . '&id=' . $row['primary_id_field'] . '&do=delete' ),
|
||||
'link' => Url::internal( 'app=cms&module=databases&controller=records&database_id=' . Request::i()->database_id . '&id=' . $row['primary_id_field'] . '&do=delete' ),
|
||||
'data' => array( 'delete' => '' )
|
||||
);
|
||||
}
|
||||
@@ -180,10 +211,11 @@ class _records extends \IPS\Dispatcher\Controller
|
||||
$table->parsers = array(
|
||||
'field_' . $database->field_title => function( $val, $row ) use ($database)
|
||||
{
|
||||
/* @var RecordsClass $class */
|
||||
$class = '\IPS\cms\Records' . $database->id;
|
||||
$val = $class::load( $row['primary_id_field'] )->_title;
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'records', 'cms', 'admin' )->title( $row, $val );
|
||||
return Theme::i()->getTemplate( 'records', 'cms', 'admin' )->title( $row, $val );
|
||||
},
|
||||
'category_id' => function( $val ) use ($database)
|
||||
{
|
||||
@@ -191,11 +223,12 @@ class _records extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
try
|
||||
{
|
||||
/* @var CategoriesClass $class */
|
||||
$class = '\IPS\cms\Categories' . $database->id;
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'records', 'cms', 'admin' )->category( $class::load( $val ) );
|
||||
return Theme::i()->getTemplate( 'records', 'cms', 'admin' )->category( $class::load( $val ) );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
catch( OutOfRangeException $e )
|
||||
{
|
||||
return '';
|
||||
}
|
||||
@@ -205,34 +238,34 @@ class _records extends \IPS\Dispatcher\Controller
|
||||
'record_publish_date' => function( $val, $row )
|
||||
{
|
||||
$val = ( ! empty( $val ) ) ? $val : $row['record_saved'];
|
||||
return \IPS\DateTime::ts( $val )->localeDate();
|
||||
return DateTime::ts( $val )->localeDate();
|
||||
}
|
||||
);
|
||||
|
||||
/* Add a button for managing DB settings */
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'cms', 'databases', 'databases_edit' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'cms', 'databases', 'databases_edit' ) )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['actions']['databasemanage'] = array(
|
||||
Output::i()->sidebar['actions']['databasemanage'] = array(
|
||||
'title' => 'cms_manage_database',
|
||||
'icon' => 'wrench',
|
||||
'link' => \IPS\Http\Url::internal( 'app=cms&module=databases&controller=databases&do=form&id=' . $database->_id ),
|
||||
'link' => Url::internal( 'app=cms&module=databases&controller=databases&do=form&id=' . $database->_id ),
|
||||
'data' => NULL
|
||||
);
|
||||
}
|
||||
|
||||
\IPS\Output::i()->sidebar['actions']['databasepermissions'] = array(
|
||||
Output::i()->sidebar['actions']['databasepermissions'] = array(
|
||||
'title' => 'cms_database_permissions',
|
||||
'icon' => 'lock',
|
||||
'link' => \IPS\Http\Url::internal( 'app=cms&module=databases&controller=databases&do=permissions&id=' . $database->_id ),
|
||||
'link' => Url::internal( 'app=cms&module=databases&controller=databases&do=permissions&id=' . $database->_id ),
|
||||
'data' => NULL
|
||||
);
|
||||
|
||||
/* Reset languages */
|
||||
\IPS\Member::loggedIn()->language()->words[ $table->langPrefix . $database->field_title ] = \IPS\Member::loggedIn()->language()->addToStack($table->langPrefix . 'title');
|
||||
Member::loggedIn()->language()->words[ $table->langPrefix . $database->field_title ] = Member::loggedIn()->language()->addToStack($table->langPrefix . 'title');
|
||||
|
||||
/* Display */
|
||||
\IPS\Output::i()->output = (string) $table;
|
||||
\IPS\Output::i()->title = $title;
|
||||
Output::i()->output = (string) $table;
|
||||
Output::i()->title = $title;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -240,31 +273,29 @@ class _records extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
public function delete() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'records_delete' );
|
||||
Dispatcher::i()->checkAcpPermission( 'records_delete' );
|
||||
|
||||
/* Make sure the user confirmed the deletion */
|
||||
\IPS\Request::i()->confirmedDelete();
|
||||
Request::i()->confirmedDelete();
|
||||
|
||||
$recordClass = '\IPS\cms\Records' . \IPS\Request::i()->database_id;
|
||||
/* @var RecordsClass $recordClass */
|
||||
$recordClass = '\IPS\cms\Records' . Request::i()->database_id;
|
||||
|
||||
try
|
||||
{
|
||||
$record = $recordClass::load( \IPS\Request::i()->id );
|
||||
$record = $recordClass::load( Request::i()->id );
|
||||
$record->delete();
|
||||
|
||||
\IPS\Session::i()->modLog( 'acplogs__cms_deleted_record', array( $record->mapped('title') => FALSE, 'content_db_' . $record->database()->_id => TRUE ) );
|
||||
Session::i()->modLog( 'acplogs__cms_deleted_record', array( $record->mapped('title') => FALSE, 'content_db_' . $record->database()->_id => TRUE ) );
|
||||
}
|
||||
catch( \OutofRangeException $ex )
|
||||
catch( OutofRangeException $ex )
|
||||
{
|
||||
\IPS\Output::i()->error( 'no_module_permission', '2T253/1', 403, '' );
|
||||
}
|
||||
Output::i()->error( 'no_module_permission', '2T253/1', 403, '' );
|
||||
}
|
||||
|
||||
/* Clear guest page caches */
|
||||
\IPS\Data\Cache::i()->clearAll();
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=cms&module=databases&controller=records&database_id=' . \IPS\Request::i()->database_id ), 'record_deleted' );
|
||||
Output::i()->redirect( Url::internal( 'app=cms&module=databases&controller=records&database_id=' . Request::i()->database_id ), 'record_deleted' );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -272,11 +303,13 @@ class _records extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function select()
|
||||
protected function select() : void
|
||||
{
|
||||
$move = isset( \IPS\Request::i()->move ) ? \IPS\Request::i()->move : NULL;
|
||||
$catClass = 'IPS\cms\Categories' . \IPS\Request::i()->database_id;
|
||||
$recordClass = 'IPS\cms\Records' . \IPS\Request::i()->database_id;
|
||||
/* @var RecordsClass $recordClass
|
||||
* @var CategoriesClass $catClass */
|
||||
$move = isset( Request::i()->move ) ? Request::i()->move : NULL;
|
||||
$catClass = 'IPS\cms\Categories' . Request::i()->database_id;
|
||||
$recordClass = 'IPS\cms\Records' . Request::i()->database_id;
|
||||
$category = NULL;
|
||||
$record = NULL;
|
||||
|
||||
@@ -287,13 +320,13 @@ class _records extends \IPS\Dispatcher\Controller
|
||||
$record = $recordClass::load( $move );
|
||||
$category = $catClass::load( $record->category_id );
|
||||
}
|
||||
catch( \OutOfRangeException $e ) { }
|
||||
catch( OutOfRangeException $e ) { }
|
||||
}
|
||||
|
||||
$form = new \IPS\Helpers\Form( 'select_category', 'continue' );
|
||||
$form->class = 'ipsForm_vertical ipsForm_noLabels';
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'category', $category, TRUE, array(
|
||||
'url' => \IPS\Http\Url::internal( 'app=cms&module=databases&controller=records&do=select&database_id=' . \IPS\Request::i()->database_id . ( ( $move ) ? '&move=' . $move : '' ) ),
|
||||
$form = new Form( 'select_category', 'continue' );
|
||||
$form->class = 'ipsForm--vertical ipsForm--pre-add-record ipsForm_noLabels';
|
||||
$form->add( new Node( 'content_db_table_category_id', $category, TRUE, array(
|
||||
'url' => Url::internal( 'app=cms&module=databases&controller=records&do=select&database_id=' . Request::i()->database_id . ( ( $move ) ? '&move=' . $move : '' ) ),
|
||||
'class' => $catClass,
|
||||
'multiple' => false,
|
||||
'permissionCheck' => function( $node )
|
||||
@@ -316,25 +349,25 @@ class _records extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
if ( $move and $record )
|
||||
{
|
||||
$record->move( $values['category'] );
|
||||
$record->move( $values['content_db_table_category_id'] );
|
||||
|
||||
\IPS\Session::i()->log( 'acplogs__cms_moved_record', array(
|
||||
Session::i()->log( 'acplogs__cms_moved_record', array(
|
||||
$record->mapped('title') => FALSE,
|
||||
$category->_title => TRUE,
|
||||
$values['category']->_title => TRUE,
|
||||
$record->database()->_title => TRUE
|
||||
) );
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=cms&module=databases&controller=records&database_id=' . \IPS\Request::i()->database_id ), 'completed' );
|
||||
Output::i()->redirect( Url::internal( 'app=cms&module=databases&controller=records&database_id=' . Request::i()->database_id ), 'completed' );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=cms&module=databases&controller=records&do=form&database_id=' . \IPS\Request::i()->database_id . '&category_id=' . $values['category']->id ) );
|
||||
Output::i()->redirect( Url::internal( 'app=cms&module=databases&controller=records&do=form&database_id=' . Request::i()->database_id . '&category_id=' . $values['content_db_table_category_id']->id ) );
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'database_select_category' );
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'records' )->categorySelector( $form );
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack( 'database_select_category' );
|
||||
Output::i()->output = (string) $form;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -342,30 +375,29 @@ class _records extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function form()
|
||||
public function form() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'records_edit' );
|
||||
Dispatcher::i()->checkAcpPermission( 'records_edit' );
|
||||
|
||||
$database = \IPS\cms\Databases::load( \IPS\Request::i()->database_id );
|
||||
$title = \IPS\Member::loggedIn()->language()->addToStack('content_record_db_title', TRUE, array( 'sprintf' => array( $database->_title ) ) );
|
||||
$database = Databases::load( Request::i()->database_id );
|
||||
$title = Member::loggedIn()->language()->addToStack('content_record_db_title', TRUE, array( 'sprintf' => array( $database->_title ) ) );
|
||||
|
||||
$current = NULL;
|
||||
$customValues = array();
|
||||
|
||||
/* @var RecordsClass $class */
|
||||
$class = 'IPS\cms\Records' . Request::i()->database_id;
|
||||
|
||||
$class = 'IPS\cms\Records' . \IPS\Request::i()->database_id;
|
||||
|
||||
if ( \IPS\Request::i()->id )
|
||||
if ( Request::i()->id )
|
||||
{
|
||||
$current = $class::load( \IPS\Request::i()->id );
|
||||
$customValues = $current->fieldValues();
|
||||
$current = $class::load( Request::i()->id );
|
||||
}
|
||||
|
||||
$fieldsClass = 'IPS\cms\Fields' . \IPS\Request::i()->database_id;
|
||||
$catClass = 'IPS\cms\Categories' . \IPS\Request::i()->database_id;
|
||||
$container = ( $current ) ? $catClass::load( $current->category_id ) : ( isset( \IPS\Request::i()->category_id ) ? $catClass::load( \IPS\Request::i()->category_id ) : NULL );
|
||||
|
||||
/* @var CategoriesClass $catClass */
|
||||
$catClass = 'IPS\cms\Categories' . Request::i()->database_id;
|
||||
$container = ( $current ) ? $catClass::load( $current->category_id ) : ( isset( Request::i()->category_id ) ? $catClass::load( Request::i()->category_id ) : NULL );
|
||||
$manuallyHandledFields = array( 'record_publish_date', 'record_expiry_date', 'record_allow_comments', 'record_comment_cutoff', 'record_meta_keywords', 'record_meta_description' );
|
||||
|
||||
$form = new \IPS\Helpers\Form();
|
||||
$form = new Form();
|
||||
|
||||
$form->addTab( 'content_database_record_tab_content' );
|
||||
|
||||
@@ -374,7 +406,7 @@ class _records extends \IPS\Dispatcher\Controller
|
||||
|
||||
foreach( $formElements as $name => $field )
|
||||
{
|
||||
if ( \in_array( $name, $manuallyHandledFields ) )
|
||||
if ( in_array( $name, $manuallyHandledFields ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -405,7 +437,7 @@ class _records extends \IPS\Dispatcher\Controller
|
||||
$form->add( $formElements['record_expiry_date'] );
|
||||
}
|
||||
|
||||
$currentMember = ( $current ? \IPS\Member::load( $current->member_id ) : NULL );
|
||||
$currentMember = ( $current ? Member::load( $current->member_id ) : NULL );
|
||||
$options = array(
|
||||
'me' => 'record_author_choice_me',
|
||||
'notme' => 'record_author_choice_notme'
|
||||
@@ -416,17 +448,21 @@ class _records extends \IPS\Dispatcher\Controller
|
||||
$options['guest'] = 'record_author_choice_guest';
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'record_author_choice', $currentMember ? ( $currentMember->member_id === \IPS\Member::loggedIn()->member_id ? 'me' : ( $currentMember->member_id ? 'notme' : 'guest' ) ) : 'me', FALSE, array(
|
||||
$form->add( new Radio( 'record_author_choice', $currentMember ? ( $currentMember->member_id === Member::loggedIn()->member_id ? 'me' : ( $currentMember->member_id ? 'notme' : 'guest' ) ) : 'me', FALSE, array(
|
||||
'options' => $options,
|
||||
'toggles' => array(
|
||||
'notme' => array( 'record_member_id' )
|
||||
)
|
||||
), NULL, NULL, NULL, 'record_author_choice' ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Member( 'record_member_id', ( $currentMember and $currentMember->member_id ) ? $currentMember : NULL, FALSE, array(), function( $val ) {
|
||||
if( !$val AND \IPS\Request::i()->record_author_choice == 'notme' )
|
||||
$form->add( new Form\Member( 'record_member_id', ( $currentMember and $currentMember->member_id ) ? $currentMember : NULL, null, array(), function($val ) {
|
||||
if( !$val AND Request::i()->record_author_choice == 'notme' )
|
||||
{
|
||||
throw new \DomainException( 'form_required' );
|
||||
throw new DomainException( 'form_required' );
|
||||
}
|
||||
elseif( Request::i()->record_author_choice == 'me' )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}, NULL, NULL, 'record_member_id' ) );
|
||||
|
||||
@@ -442,7 +478,7 @@ class _records extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
}
|
||||
|
||||
if ( \IPS\Member::loggedIn()->modPermission('can_content_edit_meta_tags') )
|
||||
if ( Member::loggedIn()->modPermission('can_content_edit_meta_tags') )
|
||||
{
|
||||
$form->addTab( 'content_database_record_tab_meta' );
|
||||
$form->add( $formElements['record_meta_keywords'] );
|
||||
@@ -451,8 +487,11 @@ class _records extends \IPS\Dispatcher\Controller
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
$recordClass = '\IPS\cms\Records' . \IPS\Request::i()->database_id;
|
||||
$fieldClass = '\IPS\cms\Fields' . \IPS\Request::i()->database_id;
|
||||
/* @var RecordsClass $recordClass */
|
||||
$recordClass = '\IPS\cms\Records' . Request::i()->database_id;
|
||||
|
||||
/* @var FieldsClass $fieldClass */
|
||||
$fieldClass = '\IPS\cms\Fields' . Request::i()->database_id;
|
||||
|
||||
$new = false;
|
||||
if ( empty( $current ) )
|
||||
@@ -462,14 +501,15 @@ class _records extends \IPS\Dispatcher\Controller
|
||||
|
||||
if ( ! $database->use_categories )
|
||||
{
|
||||
/* @var CategoriesClass $catClass */
|
||||
$catClass = 'IPS\cms\Categories' . $database->id;
|
||||
$category = $catClass::load( $database->get__default_category() );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( isset( \IPS\Request::i()->category_id ) )
|
||||
if ( isset( Request::i()->category_id ) )
|
||||
{
|
||||
$category = $catClass::load( \IPS\Request::i()->category_id );
|
||||
$category = $catClass::load( Request::i()->category_id );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -480,9 +520,9 @@ class _records extends \IPS\Dispatcher\Controller
|
||||
/* Claim attachments */
|
||||
foreach( $fieldClass::data() as $key => $field )
|
||||
{
|
||||
if ( mb_ucfirst( $field->type ) === 'Editor' )
|
||||
if ( IPS::mb_ucfirst( $field->type ) === 'Editor' )
|
||||
{
|
||||
\IPS\File::claimAttachments( 'RecordField_' . ( $new ? 'new' : $current->primary_id_field ) . '_' . $field->id , $current->primary_id_field, $field->id, \IPS\Request::i()->database_id );
|
||||
File::claimAttachments( 'RecordField_' . $current->primary_id_field . '_' . $field->id , $current->primary_id_field, $field->id, Request::i()->database_id );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -492,24 +532,24 @@ class _records extends \IPS\Dispatcher\Controller
|
||||
$current->record_meta_description = $values['record_meta_description'];
|
||||
|
||||
$changeAuthor = FALSE;
|
||||
if ( ! empty( \IPS\Request::i()->id ) )
|
||||
if ( ! empty( Request::i()->id ) )
|
||||
{
|
||||
if ( $values['record_author_choice'] === 'guest' )
|
||||
{
|
||||
if ( $current->member_id )
|
||||
{
|
||||
$values['record_member_id'] = new \IPS\Member;
|
||||
$values['record_member_id'] = new Member;
|
||||
$changeAuthor = TRUE;
|
||||
}
|
||||
}
|
||||
else if ( ! $current->member_id and $values['record_author_choice'] !== 'guest' )
|
||||
else if ( ! $current->member_id )
|
||||
{
|
||||
$values['record_member_id'] = ( $values['record_author_choice'] === 'me' ) ? \IPS\Member::loggedIn() : $values['record_member_id'];
|
||||
$values['record_member_id'] = ( $values['record_author_choice'] === 'me' ) ? Member::loggedIn() : $values['record_member_id'];
|
||||
$changeAuthor = TRUE;
|
||||
}
|
||||
else if ( $values['record_author_choice'] === 'me' )
|
||||
{
|
||||
$values['record_member_id'] = \IPS\Member::loggedIn();
|
||||
$values['record_member_id'] = Member::loggedIn();
|
||||
$changeAuthor = TRUE;
|
||||
}
|
||||
else if ( $values['record_author_choice'] === 'notme' and ! empty( $values['record_member_id'] ) )
|
||||
@@ -521,6 +561,7 @@ class _records extends \IPS\Dispatcher\Controller
|
||||
/* Just editing, thanks */
|
||||
if ( ! $new )
|
||||
{
|
||||
$current->processBeforeEdit( $values );
|
||||
$current->processForm( $values );
|
||||
$current->processAfterEdit( $values );
|
||||
|
||||
@@ -528,7 +569,7 @@ class _records extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
$column = $recordClass::$databaseColumnMap['date'];
|
||||
|
||||
if ( $values[ $recordClass::$formLangPrefix . 'date' ] instanceof \IPS\DateTime )
|
||||
if ( $values[ $recordClass::$formLangPrefix . 'date' ] instanceof DateTime )
|
||||
{
|
||||
$current->$column = $values[ $recordClass::$formLangPrefix . 'date' ]->getTimestamp();
|
||||
}
|
||||
@@ -543,11 +584,11 @@ class _records extends \IPS\Dispatcher\Controller
|
||||
|
||||
if ( $new )
|
||||
{
|
||||
\IPS\Session::i()->log( 'acplogs__cms_added_record', array( $current->mapped('title') => FALSE, $current->database()->_title => TRUE ) );
|
||||
Session::i()->log( 'acplogs__cms_added_record', array( $current->mapped('title') => FALSE, $current->database()->_title => TRUE ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Session::i()->modLog( 'acplogs__cms_edited_record', array( $current->mapped('title') => FALSE, $current->database()->_title => TRUE ) );
|
||||
Session::i()->modLog( 'acplogs__cms_edited_record', array( $current->mapped('title') => FALSE, $current->database()->_title => TRUE ) );
|
||||
}
|
||||
|
||||
if ( $changeAuthor )
|
||||
@@ -556,20 +597,17 @@ class _records extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
$current->changeAuthor( $values['record_member_id'] );
|
||||
}
|
||||
catch( \LogicException $ex )
|
||||
catch( LogicException $ex )
|
||||
{
|
||||
/* If the database isn't attached to a page, a call to url() when logging an author change throws this */
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear guest page caches */
|
||||
\IPS\Data\Cache::i()->clearAll();
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=cms&module=databases&controller=records&database_id=' . \IPS\Request::i()->database_id ), 'saved' );
|
||||
Output::i()->redirect( Url::internal( 'app=cms&module=databases&controller=records&database_id=' . Request::i()->database_id ), 'saved' );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->block( $current ? $title : 'add', $form, FALSE );
|
||||
\IPS\Output::i()->title = $title;
|
||||
Output::i()->output = Theme::i()->getTemplate( 'global', 'core' )->block( $current ? $title : 'add', $form, FALSE );
|
||||
Output::i()->title = $title;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -577,19 +615,20 @@ class _records extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function categoryTree()
|
||||
public function categoryTree() : void
|
||||
{
|
||||
$class = '\IPS\cms\Categories' . \IPS\Request::i()->database_id;
|
||||
/* @var CategoriesClass $class */
|
||||
$class = '\IPS\cms\Categories' . Request::i()->database_id;
|
||||
try
|
||||
{
|
||||
$category = $class::load( \IPS\Request::i()->id );
|
||||
$category = $class::load( Request::i()->id );
|
||||
$parents = iterator_to_array( $category->parents() );
|
||||
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->block( \IPS\Member::loggedIn()->language()->addToStack('content_tree_title'), \IPS\Theme::i()->getTemplate( 'records', 'cms', 'admin' )->categoryTree( $category, $parents ), FALSE );
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('content_tree_title');
|
||||
Output::i()->output = Theme::i()->getTemplate( 'global', 'core' )->block( Member::loggedIn()->language()->addToStack('content_tree_title'), Theme::i()->getTemplate( 'records', 'cms', 'admin' )->categoryTree( $category, $parents ), FALSE );
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('content_tree_title');
|
||||
|
||||
}
|
||||
catch( \Exception $ex )
|
||||
catch( Exception $ex )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -12,67 +12,88 @@
|
||||
namespace IPS\cms\modules\admin\pages;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Application;
|
||||
use IPS\cms\Blocks\Block;
|
||||
use IPS\cms\Databases;
|
||||
use IPS\cms\Pages\Page;
|
||||
use IPS\cms\Templates;
|
||||
use IPS\Db;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
use IPS\Settings;
|
||||
use IPS\Theme;
|
||||
use IPS\Widget;
|
||||
use OutOfRangeException;
|
||||
use function defined;
|
||||
use function in_array;
|
||||
use function is_numeric;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Members AJAX actions
|
||||
*/
|
||||
class _ajax extends \IPS\Dispatcher\Controller
|
||||
class ajax extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Return a CSS or HTML menu
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function loadMenu()
|
||||
public function loadMenu() : void
|
||||
{
|
||||
$request = array(
|
||||
't_location' => ( isset( \IPS\Request::i()->t_location ) ) ? \IPS\Request::i()->t_location : null,
|
||||
't_group' => ( isset( \IPS\Request::i()->t_group ) ) ? \IPS\Request::i()->t_group : null,
|
||||
't_key' => ( isset( \IPS\Request::i()->t_key ) ) ? \IPS\Request::i()->t_key : null,
|
||||
't_type' => ( isset( \IPS\Request::i()->t_type ) ) ? \IPS\Request::i()->t_type : 'templates',
|
||||
't_location' => ( isset( Request::i()->t_location ) ) ? Request::i()->t_location : null,
|
||||
't_group' => ( isset( Request::i()->t_group ) ) ? Request::i()->t_group : null,
|
||||
't_key' => ( isset( Request::i()->t_key ) ) ? Request::i()->t_key : null,
|
||||
't_type' => ( isset( Request::i()->t_type ) ) ? Request::i()->t_type : 'templates',
|
||||
);
|
||||
|
||||
switch( $request['t_type'] )
|
||||
{
|
||||
default:
|
||||
case 'template':
|
||||
$flag = \IPS\cms\Templates::RETURN_ONLY_TEMPLATE;
|
||||
$flag = Templates::RETURN_ONLY_TEMPLATE;
|
||||
break;
|
||||
case 'js':
|
||||
$flag = \IPS\cms\Templates::RETURN_ONLY_JS;
|
||||
$flag = Templates::RETURN_ONLY_JS;
|
||||
break;
|
||||
case 'css':
|
||||
$flag = \IPS\cms\Templates::RETURN_ONLY_CSS;
|
||||
$flag = Templates::RETURN_ONLY_CSS;
|
||||
break;
|
||||
}
|
||||
|
||||
$templates = \IPS\cms\Templates::buildTree( \IPS\cms\Templates::getTemplates( $flag + \IPS\cms\Templates::RETURN_DATABASE_ONLY ) );
|
||||
$templates = Templates::buildTree( Templates::getTemplates( $flag + Templates::RETURN_DATABASE_ONLY ) );
|
||||
|
||||
$current = new \IPS\cms\Templates;
|
||||
$current = new Templates;
|
||||
|
||||
if ( ! empty( $request['t_key'] ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$current = \IPS\cms\Templates::load( $request['t_key'] );
|
||||
$current = Templates::load( $request['t_key'] );
|
||||
}
|
||||
catch( \OutOfRangeException $ex )
|
||||
catch( OutOfRangeException $ex )
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'templates' )->menu( $templates, $current, $request );
|
||||
Output::i()->output = Theme::i()->getTemplate( 'templates' )->menu( $templates, $current, $request );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,31 +101,23 @@ class _ajax extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function loadTemplate()
|
||||
public function loadTemplate() : void
|
||||
{
|
||||
$t_location = \IPS\Request::i()->t_location;
|
||||
$t_key = \IPS\Request::i()->t_key;
|
||||
$t_location = Request::i()->t_location;
|
||||
$t_key = Request::i()->t_key;
|
||||
|
||||
if ( $t_location === 'block' and $t_key === '_default_' and isset( \IPS\Request::i()->block_key ) )
|
||||
if ( $t_location === 'block' and $t_key === '_default_' and isset( Request::i()->block_key ) )
|
||||
{
|
||||
/* Find it from the normal template system */
|
||||
if ( isset( \IPS\Request::i()->block_app ) )
|
||||
{
|
||||
$plugin = \IPS\Widget::load( \IPS\Application::load( \IPS\Request::i()->block_app ), \IPS\Request::i()->block_key, mt_rand() );
|
||||
}
|
||||
else
|
||||
{
|
||||
$plugin = \IPS\Widget::load( \IPS\Plugin::load( \IPS\Request::i()->block_plugin ), \IPS\Request::i()->block_key, mt_rand() );
|
||||
}
|
||||
|
||||
|
||||
$plugin = Widget::load( Application::load( Request::i()->block_app ), Request::i()->block_key, mt_rand() );
|
||||
$location = $plugin->getTemplateLocation();
|
||||
|
||||
$templateBits = \IPS\Theme::master()->getRawTemplates( $location['app'], $location['location'], $location['group'], \IPS\Theme::RETURN_ALL );
|
||||
$templateBits = Theme::master()->getAllTemplates( $location['app'], $location['location'], $location['group'], Theme::RETURN_ALL );
|
||||
$templateBit = $templateBits[ $location['app'] ][ $location['location'] ][ $location['group'] ][ $location['name'] ];
|
||||
|
||||
if ( ! isset( \IPS\Request::i()->noencode ) OR ! \IPS\Request::i()->noencode )
|
||||
if ( ! isset( Request::i()->noencode ) OR ! Request::i()->noencode )
|
||||
{
|
||||
$templateBit['template_content'] = htmlentities( $templateBit['template_content'], ENT_DISALLOWED, 'UTF-8', TRUE );
|
||||
$templateBit['template_content'] = htmlentities( $templateBit['template_content'], ENT_DISALLOWED, 'UTF-8' );
|
||||
}
|
||||
|
||||
$templateArray = array(
|
||||
@@ -126,18 +139,18 @@ class _ajax extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
try
|
||||
{
|
||||
if ( \is_numeric( $t_key ) )
|
||||
if ( is_numeric( $t_key ) )
|
||||
{
|
||||
$template = \IPS\cms\Templates::load( $t_key, 'template_id' );
|
||||
$template = Templates::load( $t_key, 'template_id' );
|
||||
}
|
||||
else
|
||||
{
|
||||
$template = \IPS\cms\Templates::load( $t_key );
|
||||
$template = Templates::load( $t_key );
|
||||
}
|
||||
}
|
||||
catch( \OutOfRangeException $ex )
|
||||
catch( OutOfRangeException $ex )
|
||||
{
|
||||
\IPS\Output::i()->json( array( 'error' => true ) );
|
||||
Output::i()->json( array( 'error' => true ) );
|
||||
}
|
||||
|
||||
if ( $template !== null )
|
||||
@@ -147,7 +160,7 @@ class _ajax extends \IPS\Dispatcher\Controller
|
||||
'template_key' => $template->key,
|
||||
'template_title' => $template->title,
|
||||
'template_desc' => $template->desc,
|
||||
'template_content' => ( isset( \IPS\Request::i()->noencode ) AND \IPS\Request::i()->noencode ) ? $template->content : htmlentities( $template->content, ENT_DISALLOWED, 'UTF-8', TRUE ),
|
||||
'template_content' => ( isset( Request::i()->noencode ) AND Request::i()->noencode ) ? $template->content : htmlentities( $template->content, ENT_DISALLOWED, 'UTF-8' ),
|
||||
'template_location' => $template->location,
|
||||
'template_group' => $template->group,
|
||||
'template_container' => $template->container,
|
||||
@@ -159,13 +172,13 @@ class _ajax extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
}
|
||||
|
||||
if ( \IPS\Request::i()->show == 'json' )
|
||||
if ( Request::i()->show == 'json' )
|
||||
{
|
||||
\IPS\Output::i()->json( $templateArray );
|
||||
Output::i()->json( $templateArray );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->blankTemplate( \IPS\Theme::i()->getTemplate( 'templates', 'cms', 'admin' )->viewTemplate( $templateArray ) ), 200, 'text/html' );
|
||||
Output::i()->sendOutput( Theme::i()->getTemplate( 'global', 'core' )->blankTemplate( Theme::i()->getTemplate( 'templates', 'cms', 'admin' )->viewTemplate( $templateArray ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,32 +187,32 @@ class _ajax extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function searchtemplates()
|
||||
public function searchtemplates() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'template_manage' );
|
||||
Dispatcher::i()->checkAcpPermission( 'template_manage' );
|
||||
|
||||
$where = array();
|
||||
if ( \IPS\Request::i()->term )
|
||||
if ( Request::i()->term )
|
||||
{
|
||||
$where[] = array( '( LOWER(template_title) LIKE ? OR LOWER(template_content) LIKE ? )', '%' . mb_strtolower( \IPS\Request::i()->term ) . '%', '%' . mb_strtolower( \IPS\Request::i()->term ) . '%' );
|
||||
$where[] = array( '( LOWER(template_title) LIKE ? OR LOWER(template_content) LIKE ? )', '%' . mb_strtolower( Request::i()->term ) . '%', '%' . mb_strtolower( Request::i()->term ) . '%' );
|
||||
}
|
||||
|
||||
if ( ! \in_array( 'custom', explode( ',', \IPS\Request::i()->filters ) ) )
|
||||
if ( ! in_array( 'custom', explode( ',', Request::i()->filters ) ) )
|
||||
{
|
||||
$where[] = array( 'template_master=1 OR (template_user_created=1 and template_user_edited=0)' );
|
||||
}
|
||||
|
||||
if ( ! \in_array( 'unmodified', explode( ',', \IPS\Request::i()->filters ) ) )
|
||||
if ( ! in_array( 'unmodified', explode( ',', Request::i()->filters ) ) )
|
||||
{
|
||||
$where[] = array( 'template_user_created=1 and template_user_edited=1' );
|
||||
}
|
||||
|
||||
if ( isset( \IPS\Request::i()->type ) )
|
||||
if ( isset( Request::i()->type ) )
|
||||
{
|
||||
$where[] = array( 'template_type=?', \IPS\Request::i()->type );
|
||||
$where[] = array( 'template_type=?', Request::i()->type );
|
||||
}
|
||||
|
||||
$select = \IPS\Db::i()->select(
|
||||
$select = Db::i()->select(
|
||||
'*',
|
||||
'cms_templates',
|
||||
$where,
|
||||
@@ -212,7 +225,7 @@ class _ajax extends \IPS\Dispatcher\Controller
|
||||
$return[ $result['template_location'] ][ $result['template_group'] ][ $result['template_key'] ] = $result['template_title'];
|
||||
}
|
||||
|
||||
\IPS\Output::i()->json( $return );
|
||||
Output::i()->json( $return );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -220,30 +233,30 @@ class _ajax extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function loadTags()
|
||||
public function loadTags() : void
|
||||
{
|
||||
$page = NULL;
|
||||
if ( isset( \IPS\Request::i()->pageId ) )
|
||||
if ( isset( Request::i()->pageId ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$page = \IPS\cms\Pages\Page::load( \IPS\Request::i()->pageId );
|
||||
$page = Page::load( Request::i()->pageId );
|
||||
}
|
||||
catch( \OutOfRangeException $e ) {}
|
||||
catch( OutOfRangeException $e ) {}
|
||||
}
|
||||
|
||||
$tags = array();
|
||||
$tagLinks = array();
|
||||
|
||||
if ( $page and $page->id == \IPS\Settings::i()->cms_error_page )
|
||||
if ( $page and $page->id == Settings::i()->cms_error_page )
|
||||
{
|
||||
$tags['cms_error_page']['{error_message}'] = 'cms_error_page_message';
|
||||
$tags['cms_error_page']['{error_code}'] = 'cms_error_page_code';
|
||||
}
|
||||
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'cms', 'databases', 'databases_use' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'cms', 'databases', 'databases_use' ) )
|
||||
{
|
||||
foreach ( \IPS\cms\Databases::roots( NULL, NULL ) as $id => $db )
|
||||
foreach ( Databases::roots( NULL ) as $id => $db )
|
||||
{
|
||||
if ( !$db->page_id )
|
||||
{
|
||||
@@ -252,33 +265,33 @@ class _ajax extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
}
|
||||
|
||||
foreach( \IPS\cms\Blocks\Block::roots( NULL, NULL ) as $id => $block )
|
||||
foreach( Block::roots( NULL ) as $id => $block )
|
||||
{
|
||||
$tags['cms_tag_blocks']['{block="' . $block->key . '"}'] = $block->_title;
|
||||
}
|
||||
|
||||
foreach( \IPS\Db::i()->select( '*', 'cms_pages', NULL, 'page_full_path ASC', array( 0, 50 ) ) as $page )
|
||||
foreach( Db::i()->select( '*', 'cms_pages', NULL, 'page_full_path ASC', array( 0, 50 ) ) as $page )
|
||||
{
|
||||
$tags['cms_tag_pages']['{pageurl="' . $page['page_full_path'] . '"}' ] = \IPS\Member::loggedIn()->language()->addToStack( \IPS\cms\Pages\Page::$titleLangPrefix . $page['page_id'] );
|
||||
$tags['cms_tag_pages']['{pageurl="' . $page['page_full_path'] . '"}' ] = Member::loggedIn()->language()->addToStack( Page::$titleLangPrefix . $page['page_id'] );
|
||||
}
|
||||
|
||||
/* If we can manage words, then the header needs to always show */
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'languages', 'lang_words' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'core', 'languages', 'lang_words' ) )
|
||||
{
|
||||
$tags['cms_tag_lang'] = array();
|
||||
$tagLinks['cms_tag_lang'] = array(
|
||||
'icon' => 'plus',
|
||||
'title' => \IPS\Member::loggedIn()->language()->addToStack('add_word'),
|
||||
'link' => \IPS\Http\Url::internal( "app=core&module=languages&controller=languages&do=addWord" ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack( 'add_word' ), 'ipsDialog-remoteSubmit' => TRUE, 'action' => "wordForm" )
|
||||
'title' => Member::loggedIn()->language()->addToStack('add_word'),
|
||||
'link' => Url::internal( "app=core&module=languages&controller=languages&do=addWord" ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => Member::loggedIn()->language()->addToStack( 'add_word' ), 'ipsDialog-remoteSubmit' => TRUE, 'action' => "wordForm" )
|
||||
);
|
||||
}
|
||||
|
||||
foreach( \IPS\Db::i()->select( '*', 'core_sys_lang_words', array( "word_is_custom=? AND lang_id=?", 1, \IPS\Member::loggedIn()->language()->_id ) ) AS $lang )
|
||||
foreach( Db::i()->select( '*', 'core_sys_lang_words', array( "word_is_custom=? AND lang_id=?", 1, Member::loggedIn()->language()->_id ) ) AS $lang )
|
||||
{
|
||||
$tags['cms_tag_lang']['{lang="' . $lang['word_key'] . '"}'] = $lang['word_custom'] ?: $lang['word_default'];
|
||||
}
|
||||
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->blankTemplate( \IPS\Theme::i()->getTemplate( 'forms', 'core', 'global' )->editorTags( $tags, $tagLinks ) ), 200, 'text/html' );
|
||||
Output::i()->sendOutput( Theme::i()->getTemplate( 'global', 'core' )->blankTemplate( Theme::i()->getTemplate( 'forms', 'core', 'global' )->editorTags( $tags, $tagLinks ) ) );
|
||||
}
|
||||
}
|
||||
@@ -12,35 +12,57 @@
|
||||
namespace IPS\cms\modules\admin\pages;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Application;
|
||||
use IPS\cms\Blocks\Block;
|
||||
use IPS\cms\Databases;
|
||||
use IPS\Data\Store;
|
||||
use IPS\Db;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\Radio;
|
||||
use IPS\Helpers\Form\Select;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\Node\Controller;
|
||||
use IPS\Node\Model;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
use IPS\Session;
|
||||
use IPS\Theme;
|
||||
use OutOfRangeException;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* blocks
|
||||
*/
|
||||
class _blocks extends \IPS\Node\Controller
|
||||
class blocks extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Node Class
|
||||
*/
|
||||
protected $nodeClass = '\IPS\cms\Blocks\Container';
|
||||
protected string $nodeClass = '\IPS\cms\Blocks\Container';
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'block_manage' );
|
||||
Dispatcher::i()->checkAcpPermission( 'block_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -49,30 +71,32 @@ class _blocks extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function manage()
|
||||
public function manage() : void
|
||||
{
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__cms_pages_blocks');
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('menu__cms_pages_blocks');
|
||||
|
||||
/* @var Model $nodeClass */
|
||||
$nodeClass = $this->nodeClass;
|
||||
|
||||
if ( $nodeClass::canAddRoot() )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['actions']['add_meow'] = array(
|
||||
Output::i()->sidebar['actions']['add_meow'] = array(
|
||||
'primary' => true,
|
||||
'icon' => 'plus',
|
||||
'title' => 'content_block_cat_add',
|
||||
'link' => $this->url->setQueryString( 'do', 'form' ),
|
||||
'data' => ( $nodeClass::$modalForms ? array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('content_block_cat_add') ) : array() )
|
||||
'data' => ( $nodeClass::$modalForms ? array( 'ipsDialog' => '', 'ipsDialog-title' => Member::loggedIn()->language()->addToStack('content_block_cat_add') ) : array() )
|
||||
);
|
||||
}
|
||||
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'cms', 'pages', 'block_add' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'cms', 'pages', 'block_add' ) )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['actions']['add_block'] = array(
|
||||
Output::i()->sidebar['actions']['add_block'] = array(
|
||||
'primary' => true,
|
||||
'icon' => 'puzzle-piece',
|
||||
'title' => 'content_block_block_add',
|
||||
'link' => $this->url->setQueryString( array( 'do' => 'addBlockType', 'subnode' => 1 ) ),
|
||||
'data' => ( $nodeClass::$modalForms ? array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('content_block_block_add') ) : array() )
|
||||
'data' => ( $nodeClass::$modalForms ? array( 'ipsDialog' => '', 'ipsDialog-title' => Member::loggedIn()->language()->addToStack('content_block_block_add') ) : array() )
|
||||
);
|
||||
}
|
||||
parent::manage();
|
||||
@@ -83,12 +107,12 @@ class _blocks extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function delete()
|
||||
protected function delete() : void
|
||||
{
|
||||
if ( isset( \IPS\Request::i()->id ) )
|
||||
if ( isset( Request::i()->id ) )
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
\IPS\cms\Blocks\Block::deleteCompiled( \IPS\Request::i()->id );
|
||||
Session::i()->csrfCheck();
|
||||
Block::deleteCompiled( Request::i()->id );
|
||||
}
|
||||
|
||||
parent::delete();
|
||||
@@ -99,12 +123,9 @@ class _blocks extends \IPS\Node\Controller
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function _getRootButtons()
|
||||
public function _getRootButtons(): array
|
||||
{
|
||||
$nodeClass = $this->nodeClass;
|
||||
$buttons = array();
|
||||
|
||||
return $buttons;
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -113,9 +134,9 @@ class _blocks extends \IPS\Node\Controller
|
||||
* @param object $node Node returned from $nodeClass::load()
|
||||
* @return NULL|string
|
||||
*/
|
||||
public function _getRowHtml( $node )
|
||||
public function _getRowHtml( object $node ): ?string
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'blocks', 'cms', 'admin' )->rowHtml( $node );
|
||||
return Theme::i()->getTemplate( 'blocks', 'cms', 'admin' )->rowHtml( $node );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -123,99 +144,86 @@ class _blocks extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addBlockType()
|
||||
public function addBlockType() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'block_add' );
|
||||
Dispatcher::i()->checkAcpPermission( 'block_add' );
|
||||
|
||||
$form = new \IPS\Helpers\Form( 'block_add_first_step', 'next');
|
||||
$form = new Form( 'block_add_first_step', 'next');
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'content_block_add_type', 'plugin', FALSE, array(
|
||||
$form->add( new Radio( 'content_block_add_type', 'plugin', FALSE, array(
|
||||
'options' => array(
|
||||
'plugin' => 'content_block_add_type_plugin',
|
||||
'custom' => 'content_block_add_type_custom'
|
||||
'editor' => 'content_block_add_custom_type_wysiwyg',
|
||||
'html' => 'content_block_add_custom_type_html',
|
||||
),
|
||||
'toggles' => array(
|
||||
'plugin' => array( 'content_block_add_type_plugin' ),
|
||||
'custom' => array( 'content_block_add_custom_type' )
|
||||
'plugin' => array( 'content_block_add_type_plugin' )
|
||||
)
|
||||
)
|
||||
) );
|
||||
|
||||
$plugins = array();
|
||||
foreach ( \IPS\Db::i()->select( "*", 'core_widgets', array( 'embeddable=1') ) as $widget )
|
||||
foreach ( Db::i()->select( "*", 'core_widgets', array( 'embeddable=1') ) as $widget )
|
||||
{
|
||||
/* Skip the RecordFeed */
|
||||
if( $widget['app'] == 'cms' and $widget['key'] == 'RecordFeed' )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if ( $widget['app'] )
|
||||
{
|
||||
$app = \IPS\Application::load( $widget['app'] );
|
||||
$app = Application::load( $widget['app'] );
|
||||
if ( $app->enabled )
|
||||
{
|
||||
$plugins[ $app->_title ][ 'app__' . $widget['app'] . '__' . $widget['key'] ] = \IPS\Member::loggedIn()->language()->addToStack( 'block_' . $widget['key'] );
|
||||
$plugins[ $app->_title ][ 'app__' . $widget['app'] . '__' . $widget['key'] ] = Member::loggedIn()->language()->addToStack( 'block_' . $widget['key'] );
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
$plugin = \IPS\Plugin::load( $widget['plugin'] );
|
||||
if ( $plugin->enabled )
|
||||
{
|
||||
$plugins[ $plugin->_title ][ 'plugin__' . $widget['plugin'] . '__' . $widget['key'] ] = \IPS\Member::loggedIn()->language()->addToStack( 'block_' . $widget['key'] );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch ( \UnexpectedValueException $e ) { }
|
||||
catch ( \OutOfRangeException $e ) { }
|
||||
catch ( UnexpectedValueException | OutOfRangeException $e ) { }
|
||||
}
|
||||
|
||||
$disabled = array();
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'cms', 'databases', 'databases_use' ) )
|
||||
|
||||
$disabled = [];
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'cms', 'databases', 'databases_use' ) )
|
||||
{
|
||||
foreach ( \IPS\cms\Databases::databases() as $db )
|
||||
foreach ( Databases::databases() as $db )
|
||||
{
|
||||
if ( $db->page_id )
|
||||
{
|
||||
$plugins[\IPS\Member::loggedIn()->language()->addToStack( 'cms_db_feed_title' )]['db_feed_' . $db->id] = \IPS\Member::loggedIn()->language()->addToStack( 'cms_db_feed_block_with_name', FALSE, array('sprintf' => array($db->_title)) );
|
||||
$plugins[Member::loggedIn()->language()->addToStack( 'cms_db_feed_title' )]['db_feed_' . $db->id] = Member::loggedIn()->language()->addToStack( 'cms_db_feed_block_with_name', FALSE, array('sprintf' => array($db->_title)) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$disabled[] = 'db_feed_' . $db->id;
|
||||
$plugins[\IPS\Member::loggedIn()->language()->addToStack( 'cms_db_feed_title' )]['db_feed_' . $db->id] = \IPS\Member::loggedIn()->language()->addToStack( 'cms_db_feed_block_with_name_disabled', FALSE, array('sprintf' => array($db->_title)) );
|
||||
$plugins[Member::loggedIn()->language()->addToStack( 'cms_db_feed_title' )]['db_feed_' . $db->id] = Member::loggedIn()->language()->addToStack( 'cms_db_feed_block_with_name_disabled', FALSE, array('sprintf' => array($db->_title)) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'content_block_add_type_plugin', null, false, array( 'options' => $plugins, 'disabled' => $disabled ), NULL, NULL, NULL, 'content_block_add_type_plugin' ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'content_block_add_custom_type', 'editor', TRUE, array(
|
||||
'options' => array( 'editor' => 'content_block_add_custom_type_wysiwyg',
|
||||
'html' => 'content_block_add_custom_type_html',
|
||||
'php' => 'content_block_add_custom_type_php'
|
||||
) ), NULL, NULL, NULL, 'content_block_add_custom_type' ) );
|
||||
$form->add( new Select( 'content_block_add_type_plugin', null, false, array( 'options' => $plugins, 'disabled' => $disabled ), NULL, NULL, NULL, 'content_block_add_type_plugin' ) );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
if ( $values['content_block_add_type'] !== 'custom' )
|
||||
if ( $values['content_block_add_type'] == 'plugin' )
|
||||
{
|
||||
if ( mb_substr( $values['content_block_add_type_plugin'], 0, 8 ) === 'db_feed_' )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=cms&module=pages&controller=blocks&do=form&subnode=1&block_type=plugin&block_plugin=' . $values['content_block_add_type_plugin'] . '&block_plugin_app=cms&parent=' . \IPS\Request::i()->parent ) );
|
||||
Output::i()->redirect( Url::internal( 'app=cms&module=pages&controller=blocks&do=form&subnode=1&block_type=plugin&block_plugin=' . $values['content_block_add_type_plugin'] . '&block_plugin_app=cms&parent=' . Request::i()->parent ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
list( $type, $value, $key ) = explode( '__', $values['content_block_add_type_plugin'] );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=cms&module=pages&controller=blocks&do=form&subnode=1&block_type=plugin&block_plugin=' . $key . "&block_plugin_{$type}={$value}" . '&parent=' . \IPS\Request::i()->parent ) );
|
||||
Output::i()->redirect( Url::internal( 'app=cms&module=pages&controller=blocks&do=form&subnode=1&block_type=plugin&block_plugin=' . $key . "&block_plugin_{$type}={$value}" . '&parent=' . Request::i()->parent ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=cms&module=pages&controller=blocks&do=form&subnode=1&block_type=' . $values['content_block_add_type'] . '&block_editor=' . $values['content_block_add_custom_type'] . '&parent=' . \IPS\Request::i()->parent ) );
|
||||
Output::i()->redirect( Url::internal( 'app=cms&module=pages&controller=blocks&do=form&subnode=1&block_type=custom&block_editor=' . $values['content_block_add_type'] . '&parent=' . Request::i()->parent ) );
|
||||
}
|
||||
}
|
||||
|
||||
/* Display */
|
||||
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'global', 'core', 'admin' )->block( \IPS\Member::loggedIn()->language()->addToStack('content_block_block_add'), $form, FALSE );
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('content_block_block_add');
|
||||
Output::i()->output .= Theme::i()->getTemplate( 'global', 'core', 'admin' )->block( Member::loggedIn()->language()->addToStack('content_block_block_add'), $form, FALSE );
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('content_block_block_add');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -223,42 +231,42 @@ class _blocks extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function embedOptions()
|
||||
public function embedOptions() : void
|
||||
{
|
||||
$block = \IPS\cms\Blocks\Block::load( \IPS\Request::i()->id );
|
||||
$block = Block::load( Request::i()->id );
|
||||
$embedKey = md5( $block->key . time() );
|
||||
/* Output */
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('block_embed_title');
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core', 'admin' )->block( '', \IPS\Theme::i()->getTemplate( 'blocks', 'cms', 'admin' )->embedCode( $block, $embedKey ) );;
|
||||
}
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('block_embed_title');
|
||||
Output::i()->output = Theme::i()->getTemplate( 'global', 'core', 'admin' )->block( '', Theme::i()->getTemplate( 'blocks', 'cms', 'admin' )->embedCode( $block, $embedKey ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Load tags
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function loadTags()
|
||||
public function loadTags() : void
|
||||
{
|
||||
$tags = array();
|
||||
$tagLinks = array();
|
||||
|
||||
/* If we can manage words, then the header needs to always show */
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'languages', 'lang_words' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'core', 'languages', 'lang_words' ) )
|
||||
{
|
||||
$tags['cms_tag_lang'] = array();
|
||||
$tagLinks['cms_tag_lang'] = array(
|
||||
'icon' => 'plus',
|
||||
'title' => \IPS\Member::loggedIn()->language()->addToStack('add_word'),
|
||||
'link' => \IPS\Http\Url::internal( "app=core&module=languages&controller=languages&do=addWord" ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack( 'add_word' ), 'ipsDialog-remoteSubmit' => TRUE )
|
||||
'title' => Member::loggedIn()->language()->addToStack('add_word'),
|
||||
'link' => Url::internal( "app=core&module=languages&controller=languages&do=addWord" ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => Member::loggedIn()->language()->addToStack( 'add_word' ), 'ipsDialog-remoteSubmit' => TRUE )
|
||||
);
|
||||
}
|
||||
foreach( \IPS\Db::i()->select( '*', 'core_sys_lang_words', array( "word_is_custom=? AND lang_id=?", 1, \IPS\Member::loggedIn()->language()->_id ) ) AS $lang )
|
||||
foreach( Db::i()->select( '*', 'core_sys_lang_words', array( "word_is_custom=? AND lang_id=?", 1, Member::loggedIn()->language()->_id ) ) AS $lang )
|
||||
{
|
||||
$tags['cms_tag_lang']['{lang="' . $lang['word_key'] . '"}'] = $lang['word_custom'] ?: $lang['word_default'];
|
||||
}
|
||||
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->blankTemplate( \IPS\Theme::i()->getTemplate( 'forms', 'core', 'global' )->editorTags( $tags, $tagLinks ) ), 200, 'text/html' );
|
||||
Output::i()->sendOutput( Theme::i()->getTemplate( 'global', 'core' )->blankTemplate( Theme::i()->getTemplate( 'forms', 'core', 'global' )->editorTags( $tags, $tagLinks ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -266,26 +274,26 @@ class _blocks extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function storeTemporaryBlock()
|
||||
protected function storeTemporaryBlock() : void
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
$key = md5( mt_rand() );
|
||||
|
||||
while( isset( \IPS\Data\Store::i()->$key ) )
|
||||
while( isset( Store::i()->$key ) )
|
||||
{
|
||||
$key = md5( mt_rand() );
|
||||
}
|
||||
|
||||
$data = array();
|
||||
|
||||
foreach( \IPS\Request::i() as $k => $v )
|
||||
foreach( Request::i() as $k => $v )
|
||||
{
|
||||
$data[ $k ] = $v;
|
||||
}
|
||||
|
||||
\IPS\Data\Store::i()->$key = $data;
|
||||
Store::i()->$key = $data;
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=cms&module=pages&controller=builder&do=previewBlock&_key=" . $key, 'front' ) );
|
||||
Output::i()->redirect( Url::internal( "app=cms&module=pages&controller=builder&do=previewBlock&_key=" . $key, 'front' ) );
|
||||
}
|
||||
}
|
||||
@@ -12,41 +12,65 @@
|
||||
namespace IPS\cms\modules\admin\pages;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use Exception;
|
||||
use IPS\cms\Media as MediaClass;
|
||||
use IPS\cms\Media\Folder;
|
||||
use IPS\cms\Pages\Page;
|
||||
use IPS\cms\Templates;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\File;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\Node;
|
||||
use IPS\Helpers\Form\Upload;
|
||||
use IPS\Helpers\Tree\Tree;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\Node\Controller;
|
||||
use IPS\Output;
|
||||
use IPS\Output\Plugin\Filesize;
|
||||
use IPS\Request;
|
||||
use IPS\Session;
|
||||
use IPS\Theme;
|
||||
use OutOfRangeException;
|
||||
use function count;
|
||||
use function defined;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* media
|
||||
*/
|
||||
class _media extends \IPS\Node\Controller
|
||||
class media extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Node Class
|
||||
*/
|
||||
protected $nodeClass = '\IPS\cms\Media\Folder';
|
||||
protected string $nodeClass = '\IPS\cms\Media\Folder';
|
||||
|
||||
/**
|
||||
* @var string[] Additional allowed FileTypes for the media field.
|
||||
*/
|
||||
public static $additionalAllowedMediaFileTypes = array( 'pdf', 'svg' );
|
||||
|
||||
public static array $additionalAllowedMediaFileTypes = array( 'pdf', 'svg', 'woff', 'woff2', 'ttf', 'eot' );
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'media_manage' );
|
||||
Dispatcher::i()->checkAcpPermission( 'media_manage' );
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -55,24 +79,24 @@ class _media extends \IPS\Node\Controller
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function _getRootButtons()
|
||||
public function _getRootButtons(): array
|
||||
{
|
||||
$buttons = array();
|
||||
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'cms', 'pages', 'page_add' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'cms', 'pages', 'page_add' ) )
|
||||
{
|
||||
$buttons['add_folder'] = array(
|
||||
'icon' => 'folder-open',
|
||||
'title' => 'cms_add_media_folder',
|
||||
'link' => \IPS\Http\Url::internal( 'app=cms&module=pages&controller=media&do=form' ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('cms_add_media_folder') )
|
||||
'link' => Url::internal( 'app=cms&module=pages&controller=media&do=form' ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => Member::loggedIn()->language()->addToStack('cms_add_media_folder') )
|
||||
);
|
||||
|
||||
$buttons['add_page'] = array(
|
||||
'icon' => 'plus-circle',
|
||||
'title' => 'cms_add_media',
|
||||
'link' => \IPS\Http\Url::internal( 'app=cms&module=pages&controller=media&subnode=1&do=form' ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('cms_add_media') )
|
||||
'link' => Url::internal( 'app=cms&module=pages&controller=media&subnode=1&do=form' ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => Member::loggedIn()->language()->addToStack('cms_add_media') )
|
||||
);
|
||||
}
|
||||
|
||||
@@ -84,19 +108,19 @@ class _media extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function deleteByFileIds()
|
||||
public function deleteByFileIds() : void
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
if ( isset( \IPS\Request::i()->fileIds ) )
|
||||
if ( isset( Request::i()->fileIds ) )
|
||||
{
|
||||
$ids = \IPS\Request::i()->fileIds;
|
||||
$ids = Request::i()->fileIds;
|
||||
|
||||
if ( ! \is_array( $ids ) )
|
||||
if ( ! is_array( $ids ) )
|
||||
{
|
||||
$try = json_decode( $ids, TRUE );
|
||||
|
||||
if ( ! \is_array( $try ) )
|
||||
if ( ! is_array( $try ) )
|
||||
{
|
||||
$ids = array( $ids );
|
||||
}
|
||||
@@ -106,11 +130,11 @@ class _media extends \IPS\Node\Controller
|
||||
}
|
||||
}
|
||||
|
||||
if ( \count( $ids ) )
|
||||
if ( count( $ids ) )
|
||||
{
|
||||
\IPS\cms\Media::deleteByFileIds( $ids );
|
||||
MediaClass::deleteByFileIds( $ids );
|
||||
|
||||
\IPS\Session::i()->log( 'acplogs__cms_deleted_media', array( \count( $ids ) => FALSE ) );
|
||||
Session::i()->log( 'acplogs__cms_deleted_media', array( count( $ids ) => FALSE ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -118,104 +142,97 @@ class _media extends \IPS\Node\Controller
|
||||
/**
|
||||
* Show the pages tree
|
||||
*
|
||||
* @return string
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
protected function manage() : void
|
||||
{
|
||||
if ( \IPS\Theme::designersModeEnabled() )
|
||||
$url = Url::internal( "app=cms&module=pages&controller=media" );
|
||||
|
||||
/* Display the table */
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('menu__cms_pages_media');
|
||||
$output = new Tree( $url, 'menu__cms_pages_media',
|
||||
/* Get Roots */
|
||||
function () use ( $url )
|
||||
{
|
||||
$data = media::getRowsForTree( 0 );
|
||||
$rows = array();
|
||||
|
||||
foreach ( $data as $id => $row )
|
||||
{
|
||||
if( ( Request::i()->isAjax() && $row instanceof MediaClass ) || !Request::i()->isAjax() )
|
||||
{
|
||||
$rows[ $id ] = ( $row instanceof MediaClass) ? media::getItemRow( $row, $url ) : media::getFolderRow( $row, $url );
|
||||
}
|
||||
}
|
||||
|
||||
if( Request::i()->isAjax() )
|
||||
{
|
||||
Output::i()->sendOutput( json_encode( $rows ), 200, 'application/json' );
|
||||
}
|
||||
|
||||
return $data;
|
||||
},
|
||||
/* Get Row */
|
||||
function ( $id, $root ) use ( $url )
|
||||
{
|
||||
if ( $root )
|
||||
{
|
||||
return media::getFolderRow( Folder::load( $id ), $url );
|
||||
}
|
||||
else
|
||||
{
|
||||
return media::getItemRow( MediaClass::load( $id ), $url );
|
||||
}
|
||||
},
|
||||
/* Get Row Parent ID*/
|
||||
function ()
|
||||
{
|
||||
return NULL;
|
||||
},
|
||||
/* Get Children */
|
||||
function ( $id ) use ( $url )
|
||||
{
|
||||
$rows = array();
|
||||
$data = media::getRowsForTree( $id );
|
||||
|
||||
if ( ! isset( Request::i()->subnode ) )
|
||||
{
|
||||
foreach ( $data as $id => $row )
|
||||
{
|
||||
if( Request::i()->get == 'folders' && !( $row instanceof MediaClass ) )
|
||||
{
|
||||
$rows[ $id ] = media::getFolderRow( $row, $url );
|
||||
}
|
||||
elseif ( Request::i()->get == 'files' && $row instanceof MediaClass )
|
||||
{
|
||||
$rows[ $id ] = media::getItemRow( $row, $url );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if( Request::i()->isAjax() ){
|
||||
Output::i()->sendOutput( json_encode( $rows ), 200, 'application/json' );
|
||||
}
|
||||
|
||||
return $rows;
|
||||
},
|
||||
array( $this, '_getRootButtons' ),
|
||||
TRUE,
|
||||
FALSE,
|
||||
FALSE
|
||||
);
|
||||
|
||||
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, Output::i()->js( 'admin_media.js', 'cms' ) );
|
||||
Output::i()->cssFiles = array_merge( Output::i()->cssFiles, Theme::i()->css( 'media/media.css', 'cms', 'admin' ) );
|
||||
|
||||
if( Request::i()->isAjax() )
|
||||
{
|
||||
$link = \IPS\Http\Url::internal( 'app=core&module=customization&controller=themes&do=designersmode' );
|
||||
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->message( \IPS\Member::loggedIn()->language()->addToStack( 'cms_media_designer_mode_warning', FALSE, array( 'sprintf' => array( $link ) ) ), 'information', NULL, FALSE );
|
||||
Output::i()->sendOutput( $output );
|
||||
}
|
||||
else
|
||||
{
|
||||
$url = \IPS\Http\Url::internal( "app=cms&module=pages&controller=media" );
|
||||
|
||||
/* Display the table */
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__cms_pages_media');
|
||||
$output = new \IPS\Helpers\Tree\Tree( $url, 'menu__cms_pages_media',
|
||||
/* Get Roots */
|
||||
function () use ( $url )
|
||||
{
|
||||
$data = \IPS\cms\modules\admin\pages\media::getRowsForTree( 0 );
|
||||
$rows = array();
|
||||
|
||||
foreach ( $data as $id => $row )
|
||||
{
|
||||
if( ( \IPS\Request::i()->isAjax() && $row instanceof \IPS\cms\Media ) || !\IPS\Request::i()->isAjax() )
|
||||
{
|
||||
$rows[ $id ] = ( $row instanceof \IPS\cms\Media) ? \IPS\cms\modules\admin\pages\media::getItemRow( $row, $url ) : \IPS\cms\modules\admin\pages\media::getFolderRow( $row, $url );
|
||||
}
|
||||
}
|
||||
|
||||
if( \IPS\Request::i()->isAjax() ){
|
||||
\IPS\Output::i()->sendOutput( json_encode( $rows ), 200, 'application/json' );
|
||||
}
|
||||
|
||||
return $data;
|
||||
},
|
||||
/* Get Row */
|
||||
function ( $id, $root ) use ( $url )
|
||||
{
|
||||
if ( $root )
|
||||
{
|
||||
return \IPS\cms\modules\admin\pages\media::getFolderRow( \IPS\cms\Media\Folder::load( $id ), $url );
|
||||
}
|
||||
else
|
||||
{
|
||||
return \IPS\cms\modules\admin\pages\media::getItemRow( \IPS\cms\Media::load( $id ), $url );
|
||||
}
|
||||
},
|
||||
/* Get Row Parent ID*/
|
||||
function ()
|
||||
{
|
||||
return NULL;
|
||||
},
|
||||
/* Get Children */
|
||||
function ( $id ) use ( $url )
|
||||
{
|
||||
$rows = array();
|
||||
$data = \IPS\cms\modules\admin\pages\media::getRowsForTree( $id );
|
||||
|
||||
if ( ! isset( \IPS\Request::i()->subnode ) )
|
||||
{
|
||||
foreach ( $data as $id => $row )
|
||||
{
|
||||
if( \IPS\Request::i()->get == 'folders' && !( $row instanceof \IPS\cms\Media ) )
|
||||
{
|
||||
$rows[ $id ] = \IPS\cms\modules\admin\pages\media::getFolderRow( $row, $url );
|
||||
}
|
||||
elseif ( \IPS\Request::i()->get == 'files' && $row instanceof \IPS\cms\Media )
|
||||
{
|
||||
$rows[ $id ] = \IPS\cms\modules\admin\pages\media::getItemRow( $row, $url );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if( \IPS\Request::i()->isAjax() ){
|
||||
\IPS\Output::i()->sendOutput( json_encode( $rows ), 200, 'application/json' );
|
||||
}
|
||||
|
||||
return $rows;
|
||||
},
|
||||
array( $this, '_getRootButtons' ),
|
||||
TRUE,
|
||||
FALSE,
|
||||
FALSE
|
||||
);
|
||||
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'admin_media.js', 'cms' ) );
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'media/media.css', 'cms', 'admin' ) );
|
||||
|
||||
if( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( $output, 200, 'text/html' );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'media', 'cms', 'admin' )->media( $output );
|
||||
}
|
||||
Output::i()->output = Theme::i()->getTemplate( 'media', 'cms', 'admin' )->media( $output );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,26 +241,26 @@ class _media extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function replace()
|
||||
public function replace() : void
|
||||
{
|
||||
if( !isset( \IPS\Request::i()->id ) OR !\IPS\Request::i()->id )
|
||||
if( !isset( Request::i()->id ) OR !Request::i()->id )
|
||||
{
|
||||
\IPS\Output::i()->error( 'missing_media_file', '3T334/2', 404, '' );
|
||||
Output::i()->error( 'missing_media_file', '3T334/2', 404, '' );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$media = \IPS\cms\Media::load( \IPS\Request::i()->id );
|
||||
$media = MediaClass::load( Request::i()->id );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
catch( OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'missing_media_file', '3T334/3', 404, '' );
|
||||
Output::i()->error( 'missing_media_file', '3T334/3', 404, '' );
|
||||
}
|
||||
|
||||
$form = new \IPS\Helpers\Form( 'form', 'upload' );
|
||||
$form->class = 'ipsForm_vertical ipsForm_noLabels';
|
||||
$form = new Form( 'form', 'upload' );
|
||||
$form->class = 'ipsForm--vertical ipsForm--replace-file ipsForm_noLabels';
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Upload( 'media_filename', NULL, FALSE, array( 'allowedFileTypes' => array_merge( \IPS\File::$safeFileExtensions, static::$additionalAllowedMediaFileTypes ), 'obscure' => FALSE, 'storageExtension' => 'cms_Media', 'storageContainer' => 'pages_media', 'multiple' => FALSE, 'minimize' => FALSE ), NULL, NULL, NULL, 'media_filename' ) );
|
||||
$form->add( new Upload( 'media_filename', NULL, FALSE, array( 'allowedFileTypes' => array_merge( File::$safeFileExtensions, static::$additionalAllowedMediaFileTypes ), 'obscure' => FALSE, 'storageExtension' => 'cms_Media', 'storageContainer' => 'pages_media', 'multiple' => FALSE, 'minimize' => FALSE ), NULL, NULL, NULL, 'media_filename' ) );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
@@ -253,7 +270,7 @@ class _media extends \IPS\Node\Controller
|
||||
/* If we have the same extension, we will just retain the same filename */
|
||||
if( $existingFileExtension == $newFileExtension )
|
||||
{
|
||||
$media->file_object = (string) \IPS\File::create( 'cms_Media', $media->filename_stored, $values['media_filename']->contents(), 'pages_media', TRUE, NULL, FALSE );
|
||||
$media->file_object = (string) File::create( 'cms_Media', $media->filename_stored, $values['media_filename']->contents(), 'pages_media', TRUE, NULL, FALSE );
|
||||
}
|
||||
/* Otherwise we need to update the rest of the file info too */
|
||||
else
|
||||
@@ -261,10 +278,10 @@ class _media extends \IPS\Node\Controller
|
||||
$media->is_image = $values['media_filename']->isImage();
|
||||
$media->filename = $values['media_filename']->originalFilename;
|
||||
$media->filename_stored = $media->parent . '_' . $media->filename;
|
||||
$media->file_object = (string) \IPS\File::create( 'cms_Media', $media->filename_stored, $values['media_filename']->contents(), 'pages_media', TRUE, NULL, FALSE );
|
||||
$media->file_object = (string) File::create( 'cms_Media', $media->filename_stored, $values['media_filename']->contents(), 'pages_media', TRUE, NULL, FALSE );
|
||||
}
|
||||
|
||||
$media->setFullPath( ( $media->parent ? \IPS\cms\Media\Folder::load( $media->parent )->path : '' ) );
|
||||
$media->setFullPath( ( $media->parent ? Folder::load( $media->parent )->path : '' ) );
|
||||
$media->save();
|
||||
|
||||
/* Remove the original as we created a copy with a slightly altered filename */
|
||||
@@ -272,37 +289,37 @@ class _media extends \IPS\Node\Controller
|
||||
{
|
||||
$values['media_filename']->delete();
|
||||
}
|
||||
catch( \Exception $ex ) { }
|
||||
catch( Exception $ex ) { }
|
||||
|
||||
/* Wipe out included JS just in case we're using this media thing */
|
||||
\IPS\cms\Templates::deleteCompiledFiles();
|
||||
\IPS\cms\Pages\Page::deleteCachedIncludes();
|
||||
Templates::deleteCompiledFiles();
|
||||
Page::deleteCachedIncludes();
|
||||
|
||||
\IPS\Session::i()->log( 'acplogs__cms_replaced_media', array( $values['media_filename']->originalFilename => FALSE ) );
|
||||
Session::i()->log( 'acplogs__cms_replaced_media', array( $values['media_filename']->originalFilename => FALSE ) );
|
||||
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
if ( Request::i()->isAjax() )
|
||||
{
|
||||
$url = \IPS\Http\Url::internal( "app=cms&module=pages&controller=media" );
|
||||
$data = \IPS\cms\modules\admin\pages\media::getRowsForTree( $media->parent );
|
||||
$url = Url::internal( "app=cms&module=pages&controller=media" );
|
||||
$data = media::getRowsForTree( $media->parent );
|
||||
$rows = array();
|
||||
|
||||
foreach ( $data as $id => $row )
|
||||
{
|
||||
if ( $row instanceof \IPS\cms\Media )
|
||||
if ( $row instanceof MediaClass )
|
||||
{
|
||||
$rows[ $id ] = \IPS\cms\modules\admin\pages\media::getItemRow( $row, $url );
|
||||
$rows[ $id ] = media::getItemRow( $row, $url );
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->sendOutput( json_encode( array( 'fileID' => $media->id, 'folderID' => $media->parent, 'rows' => $rows ) ), 200, 'application/json' );
|
||||
Output::i()->sendOutput( json_encode( array( 'fileID' => $media->id, 'folderID' => $media->parent, 'rows' => $rows ) ), 200, 'application/json' );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=cms&module=pages&controller=media' ) );
|
||||
Output::i()->redirect( Url::internal( 'app=cms&module=pages&controller=media' ) );
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core', 'admin' )->block( 'upload', $form, FALSE );
|
||||
Output::i()->output = Theme::i()->getTemplate( 'global', 'core', 'admin' )->block( 'upload', $form, FALSE );
|
||||
}
|
||||
|
||||
|
||||
@@ -311,23 +328,23 @@ class _media extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function upload()
|
||||
public function upload() : void
|
||||
{
|
||||
$form = new \IPS\Helpers\Form( 'form', 'upload' );
|
||||
$form->class = 'ipsForm_vertical ipsForm_noLabels';
|
||||
$form = new Form( 'form', 'upload' );
|
||||
$form->class = 'ipsForm--vertical ipsForm--upload-items ipsForm_noLabels';
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Upload( 'media_filename', NULL, FALSE, array( 'allowedFileTypes' => array_merge( \IPS\File::$safeFileExtensions, static::$additionalAllowedMediaFileTypes ), 'obscure' => FALSE, 'storageExtension' => 'cms_Media', 'storageContainer' => 'pages_media', 'multiple' => true, 'minimize' => FALSE ), NULL, NULL, NULL, 'media_filename' ) );
|
||||
$form->add( new Upload( 'media_filename', NULL, FALSE, array( 'allowedFileTypes' => array_merge( File::$safeFileExtensions, static::$additionalAllowedMediaFileTypes ), 'obscure' => FALSE, 'storageExtension' => 'cms_Media', 'storageContainer' => 'pages_media', 'multiple' => true, 'minimize' => FALSE ), NULL, NULL, NULL, 'media_filename' ) );
|
||||
|
||||
if ( ! isset( \IPS\Request::i()->media_parent ) and ! \IPS\Request::i()->media_parent )
|
||||
if ( ! isset( Request::i()->media_parent ) and ! Request::i()->media_parent )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'media_parent', 0, FALSE, array(
|
||||
$form->add( new Node( 'media_parent', 0, FALSE, array(
|
||||
'class' => '\IPS\cms\Media\Folder',
|
||||
'zeroVal' => 'node_no_parent'
|
||||
) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$form->hiddenValues['media_parent_inline'] = \IPS\Request::i()->media_parent;
|
||||
$form->hiddenValues['media_parent_inline'] = Request::i()->media_parent;
|
||||
}
|
||||
|
||||
if ( $values = $form->values() )
|
||||
@@ -358,7 +375,7 @@ class _media extends \IPS\Node\Controller
|
||||
$filename = mb_substr( $filename, mb_strlen( $prefix ) );
|
||||
}
|
||||
|
||||
$new = new \IPS\cms\Media;
|
||||
$new = new MediaClass;
|
||||
$new->filename = $filename;
|
||||
$new->filename_stored = $parent . '_' . $filename;
|
||||
$new->is_image = $media->isImage();
|
||||
@@ -367,41 +384,41 @@ class _media extends \IPS\Node\Controller
|
||||
$new->file_object = (string) $media;
|
||||
$new->save();
|
||||
|
||||
$new->setFullPath( ( $parent ? \IPS\cms\Media\Folder::load( $parent )->path : '' ) );
|
||||
$new->setFullPath( ( $parent ? Folder::load( $parent )->path : '' ) );
|
||||
$new->save();
|
||||
|
||||
$count++;
|
||||
}
|
||||
|
||||
/* Wipe out included JS just in case we're using this media thing */
|
||||
\IPS\cms\Templates::deleteCompiledFiles();
|
||||
\IPS\cms\Pages\Page::deleteCachedIncludes();
|
||||
Templates::deleteCompiledFiles();
|
||||
Page::deleteCachedIncludes();
|
||||
|
||||
\IPS\Session::i()->log( 'acplogs__cms_uploaded_media', array( $count => FALSE ) );
|
||||
Session::i()->log( 'acplogs__cms_uploaded_media', array( $count => FALSE ) );
|
||||
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
if ( Request::i()->isAjax() )
|
||||
{
|
||||
$url = \IPS\Http\Url::internal( "app=cms&module=pages&controller=media" );
|
||||
$data = \IPS\cms\modules\admin\pages\media::getRowsForTree( $parent );
|
||||
$url = Url::internal( "app=cms&module=pages&controller=media" );
|
||||
$data = media::getRowsForTree( $parent );
|
||||
$rows = array();
|
||||
|
||||
foreach ( $data as $id => $row )
|
||||
{
|
||||
if ( $row instanceof \IPS\cms\Media )
|
||||
if ( $row instanceof MediaClass )
|
||||
{
|
||||
$rows[ $id ] = \IPS\cms\modules\admin\pages\media::getItemRow( $row, $url );
|
||||
$rows[ $id ] = media::getItemRow( $row, $url );
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->sendOutput( json_encode( array( 'count' => $count, 'folderID' => $parent, 'rows' => $rows ) ), 200, 'application/json' );
|
||||
Output::i()->sendOutput( json_encode( array( 'count' => $count, 'folderID' => $parent, 'rows' => $rows ) ), 200, 'application/json' );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=cms&module=pages&controller=media' ) );
|
||||
Output::i()->redirect( Url::internal( 'app=cms&module=pages&controller=media' ) );
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core', 'admin' )->block( 'upload', $form, FALSE );
|
||||
Output::i()->output = Theme::i()->getTemplate( 'global', 'core', 'admin' )->block( 'upload', $form, FALSE );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -409,13 +426,13 @@ class _media extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function search()
|
||||
protected function search() : void
|
||||
{
|
||||
$rows = array();
|
||||
$url = \IPS\Http\Url::internal( "app=cms&module=pages&controller=media" );
|
||||
$url = Url::internal( "app=cms&module=pages&controller=media" );
|
||||
|
||||
/* Get results */
|
||||
$items = \IPS\cms\Media::search( 'media_filename', \IPS\Request::i()->input, 'media_filename' );
|
||||
$items = MediaClass::search( 'media_filename', Request::i()->input, 'media_filename' );
|
||||
|
||||
/* Convert to HTML */
|
||||
foreach ( $items as $id => $result )
|
||||
@@ -423,13 +440,13 @@ class _media extends \IPS\Node\Controller
|
||||
$rows[ $id ] = $this->getItemRow( $result, $url );
|
||||
}
|
||||
|
||||
if( \IPS\Request::i()->isAjax() )
|
||||
if( Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( json_encode( $rows ), 200, 'application/json' );
|
||||
Output::i()->sendOutput( json_encode( $rows ), 200, 'application/json' );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'trees', 'core' )->rows( $rows, '' );
|
||||
Output::i()->output = Theme::i()->getTemplate( 'trees', 'core' )->rows( $rows, '' );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -438,21 +455,21 @@ class _media extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function getFileInfo()
|
||||
protected function getFileInfo() : void
|
||||
{
|
||||
try
|
||||
{
|
||||
$row = \IPS\cms\Media::load( \IPS\Request::i()->id );
|
||||
$fileObject = \IPS\File::get( 'cms_Media', $row->file_object );
|
||||
$row = MediaClass::load( Request::i()->id );
|
||||
$fileObject = File::get( 'cms_Media', $row->file_object );
|
||||
}
|
||||
catch( \OutOfRangeException $ex )
|
||||
catch( OutOfRangeException $ex )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Make a human-readable size */
|
||||
$filesize = \IPS\Output\Plugin\Filesize::humanReadableFilesize( $fileObject->filesize() );
|
||||
\IPS\Member::loggedIn()->language()->parseOutputForDisplay( $filesize );
|
||||
$filesize = Filesize::humanReadableFilesize( $fileObject->filesize() );
|
||||
Member::loggedIn()->language()->parseOutputForDisplay( $filesize );
|
||||
|
||||
$output = array(
|
||||
'fileSize' => $filesize,
|
||||
@@ -466,60 +483,61 @@ class _media extends \IPS\Node\Controller
|
||||
$output['dimensions'] = $dimensions[0] . ' x ' . $dimensions[1];
|
||||
}
|
||||
|
||||
\IPS\Output::i()->sendOutput( json_encode( $output ), 200, 'application/json' );
|
||||
Output::i()->sendOutput( json_encode( $output ), 200, 'application/json' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return HTML for a page row
|
||||
*
|
||||
* @param array $item Row data
|
||||
* @param object $url \IPS\Http\Url object
|
||||
* @param MediaClass $item Row data
|
||||
* @param object $url \IPS\Http\Url object
|
||||
* @return string HTML
|
||||
*/
|
||||
public static function getItemRow( $item, $url )
|
||||
public static function getItemRow( MediaClass $item, object $url ): string
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'media', 'cms', 'admin' )->fileListing( $url, $item );
|
||||
return Theme::i()->getTemplate( 'media', 'cms', 'admin' )->fileListing( $url, $item );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return HTML for a folder row
|
||||
*
|
||||
* @param array $folder Row data
|
||||
* @param object $url \IPS\Http\Url object
|
||||
* @param MediaClass|Folder $folder Row data
|
||||
* @param Url $url \IPS\Http\Url object
|
||||
* @return string HTML
|
||||
*/
|
||||
public static function getFolderRow( $folder, $url )
|
||||
public static function getFolderRow( MediaClass|Folder $folder, Url $url ): string
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'media', 'cms', 'admin' )->folderRow( $url, $folder );
|
||||
return Theme::i()->getTemplate( 'media', 'cms', 'admin' )->folderRow( $url, $folder );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fetch rows of folders/pages
|
||||
*
|
||||
* @param int $folderId Parent ID to fetch from
|
||||
* @param int $folderId Parent ID to fetch from
|
||||
* @return array
|
||||
*/
|
||||
public static function getRowsForTree( $folderId=0 )
|
||||
public static function getRowsForTree( int $folderId=0 ) : array
|
||||
{
|
||||
try
|
||||
{
|
||||
if ( $folderId === 0 )
|
||||
{
|
||||
$folders = \IPS\cms\Media\Folder::roots();
|
||||
$folders = Folder::roots();
|
||||
}
|
||||
else
|
||||
{
|
||||
$folders = \IPS\cms\Media\Folder::load( $folderId )->children( NULL, NULL, FALSE );
|
||||
$folders = Folder::load( $folderId )->children( NULL, NULL, FALSE );
|
||||
}
|
||||
}
|
||||
catch( \OutOfRangeException $ex )
|
||||
catch( OutOfRangeException $ex )
|
||||
{
|
||||
$folders = array();
|
||||
}
|
||||
|
||||
$media = \IPS\cms\Media::getChildren( $folderId );
|
||||
$media = MediaClass::getChildren( $folderId );
|
||||
|
||||
return \IPS\cms\Media\Folder::munge( $folders, $media );
|
||||
return Folder::munge( $folders, $media );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,40 +13,69 @@
|
||||
namespace IPS\cms\modules\admin\pages;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\cms\Pages\Folder;
|
||||
use IPS\cms\Pages\Page;
|
||||
use IPS\Data\Store;
|
||||
use IPS\Db;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Helpers\Badge;
|
||||
use IPS\Helpers\Badge\Icon;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\Radio;
|
||||
use IPS\Helpers\Tree\Tree;
|
||||
use IPS\Http\url;
|
||||
use IPS\Member;
|
||||
use IPS\Node\Controller;
|
||||
use IPS\Node\Model;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
use IPS\Session;
|
||||
use IPS\Settings;
|
||||
use IPS\Theme;
|
||||
use OutOfRangeException;
|
||||
use UnderflowException;
|
||||
use function count;
|
||||
use function defined;
|
||||
use function strpos;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Page management
|
||||
*/
|
||||
class _pages extends \IPS\Node\Controller
|
||||
class pages extends Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
public static bool $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Node Class
|
||||
*/
|
||||
protected $nodeClass = '\IPS\cms\Pages\Folder';
|
||||
protected string $nodeClass = '\IPS\cms\Pages\Folder';
|
||||
|
||||
/**
|
||||
* Store the database page map to prevent many queries
|
||||
*/
|
||||
protected static $pageToDatabaseMap = NULL;
|
||||
protected static ?array $pageToDatabaseMap = NULL;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'page_manage' );
|
||||
Dispatcher::i()->checkAcpPermission( 'page_manage' );
|
||||
|
||||
static::$pageToDatabaseMap = iterator_to_array( Db::i()->select( 'database_id, database_page_id', 'cms_databases', array( 'database_page_id > 0' ) )->setKeyField('database_page_id')->setValueField('database_id') );
|
||||
|
||||
parent::execute();
|
||||
}
|
||||
|
||||
@@ -55,36 +84,32 @@ class _pages extends \IPS\Node\Controller
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function _getRootButtons()
|
||||
public function _getRootButtons(): array
|
||||
{
|
||||
$nodeClass = $this->nodeClass;
|
||||
$buttons = array();
|
||||
|
||||
return $buttons;
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the pages tree
|
||||
*
|
||||
* @return string
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
protected function manage() : void
|
||||
{
|
||||
$url = \IPS\Http\Url::internal( "app=cms&module=pages&controller=pages" );
|
||||
static::$pageToDatabaseMap = iterator_to_array( \IPS\Db::i()->select( 'database_id, database_page_id', 'cms_databases', array( 'database_page_id > 0' ) )->setKeyField('database_page_id')->setValueField('database_id') );
|
||||
$url = Url::internal( "app=cms&module=pages&controller=pages" );
|
||||
|
||||
/* Display the table */
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__cms_pages_pages');
|
||||
\IPS\Output::i()->output = new \IPS\Helpers\Tree\Tree( $url, 'menu__cms_pages_pages',
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack('menu__cms_pages_pages');
|
||||
Output::i()->output = new Tree( $url, 'menu__cms_pages_pages',
|
||||
/* Get Roots */
|
||||
function () use ( $url )
|
||||
{
|
||||
$data = \IPS\cms\modules\admin\pages\pages::getRowsForTree( 0 );
|
||||
$data = pages::getRowsForTree( 0 );
|
||||
$rows = array();
|
||||
|
||||
foreach ( $data as $id => $row )
|
||||
{
|
||||
$rows[ $id ] = ( $row instanceof \IPS\cms\Pages\Page ) ? \IPS\cms\modules\admin\pages\pages::getPageRow( $row, $url ) : \IPS\cms\modules\admin\pages\pages::getFolderRow( $row, $url );
|
||||
$rows[ $id ] = ( $row instanceof Page ) ? pages::getPageRow( $row, $url ) : pages::getFolderRow( $row, $url );
|
||||
}
|
||||
|
||||
return $rows;
|
||||
@@ -94,11 +119,11 @@ class _pages extends \IPS\Node\Controller
|
||||
{
|
||||
if ( $root )
|
||||
{
|
||||
return \IPS\cms\modules\admin\pages\pages::getFolderRow( \IPS\cms\Pages\Folder::load( $id ), $url );
|
||||
return pages::getFolderRow( Folder::load( $id ), $url );
|
||||
}
|
||||
else
|
||||
{
|
||||
return \IPS\cms\modules\admin\pages\pages::getPageRow( \IPS\cms\Pages\Page::load( $id ), $url );
|
||||
return pages::getPageRow( Page::load( $id ), $url );
|
||||
}
|
||||
},
|
||||
/* Get Row Parent ID*/
|
||||
@@ -110,13 +135,13 @@ class _pages extends \IPS\Node\Controller
|
||||
function ( $id ) use ( $url )
|
||||
{
|
||||
$rows = array();
|
||||
$data = \IPS\cms\modules\admin\pages\pages::getRowsForTree( $id );
|
||||
$data = pages::getRowsForTree( $id );
|
||||
|
||||
if ( ! isset( \IPS\Request::i()->subnode ) )
|
||||
if ( ! isset( Request::i()->subnode ) )
|
||||
{
|
||||
foreach ( $data as $id => $row )
|
||||
{
|
||||
$rows[ $id ] = ( $row instanceof \IPS\cms\Pages\Page ) ? \IPS\cms\modules\admin\pages\pages::getPageRow( $row, $url ) : \IPS\cms\modules\admin\pages\pages::getFolderRow( $row, $url );
|
||||
$rows[ $id ] = ( $row instanceof Page ) ? pages::getPageRow( $row, $url ) : pages::getFolderRow( $row, $url );
|
||||
}
|
||||
}
|
||||
return $rows;
|
||||
@@ -127,22 +152,21 @@ class _pages extends \IPS\Node\Controller
|
||||
FALSE
|
||||
);
|
||||
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'cms', 'pages', 'page_add' ) )
|
||||
if ( Member::loggedIn()->hasAcpRestriction( 'cms', 'pages', 'page_add' ) )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['actions']['add_folder'] = array(
|
||||
Output::i()->sidebar['actions']['add_folder'] = array(
|
||||
'primary' => true,
|
||||
'icon' => 'folder-open',
|
||||
'title' => 'content_add_folder',
|
||||
'link' => \IPS\Http\Url::internal( 'app=cms&module=pages&controller=pages&do=form' ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('content_add_folder') )
|
||||
'link' => Url::internal( 'app=cms&module=pages&controller=pages&do=form' ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => Member::loggedIn()->language()->addToStack('content_add_folder') )
|
||||
);
|
||||
|
||||
\IPS\Output::i()->sidebar['actions']['add_page'] = array(
|
||||
Output::i()->sidebar['actions']['add_page'] = array(
|
||||
'primary' => true,
|
||||
'icon' => 'plus-circle',
|
||||
'title' => 'content_add_page',
|
||||
'link' => \IPS\Http\Url::internal( 'app=cms&module=pages&controller=pages&subnode=1&do=add' ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('content_add_page') )
|
||||
'link' => Url::internal( 'app=cms&module=pages&controller=pages&subnode=1&do=form&subnode=1' )
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -152,12 +176,12 @@ class _pages extends \IPS\Node\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function htaccess()
|
||||
protected function htaccess() : void
|
||||
{
|
||||
$dir = str_replace( \IPS\CP_DIRECTORY . '/index.php', '', $_SERVER['PHP_SELF'] );
|
||||
$dir = str_replace( 'admin/index.php', '', $_SERVER['PHP_SELF'] );
|
||||
$dirs = explode( '/', trim( $dir, '/' ) );
|
||||
|
||||
if ( \count( $dirs ) )
|
||||
if ( count( $dirs ) )
|
||||
{
|
||||
array_pop( $dirs );
|
||||
$dir = implode( '/', $dirs );
|
||||
@@ -170,7 +194,7 @@ class _pages extends \IPS\Node\Controller
|
||||
|
||||
$path = $dir . 'index.php';
|
||||
|
||||
if( \strpos( $dir, ' ' ) !== FALSE )
|
||||
if( strpos( $dir, ' ' ) !== FALSE )
|
||||
{
|
||||
$dir = '"' . $dir . '"';
|
||||
$path = '"' . $path . '"';
|
||||
@@ -191,42 +215,39 @@ RewriteRule . {$path} [L]
|
||||
</IfModule>
|
||||
FILE;
|
||||
|
||||
\IPS\Output::i()->sendOutput( $htaccess, 200, 'application/x-htaccess', array( 'Content-Disposition' => 'attachment; filename=.htaccess' ) );
|
||||
Output::i()->sendOutput( $htaccess, 200, 'application/x-htaccess', array( 'Content-Disposition' => 'attachment; filename=.htaccess' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Page content form
|
||||
* Add/Edit Form
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function add()
|
||||
protected function form() : void
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'page_add' );
|
||||
|
||||
$form = new \IPS\Helpers\Form( 'form', 'next' );
|
||||
$form->hiddenValues['parent'] = ( isset( \IPS\Request::i()->parent ) ) ? \IPS\Request::i()->parent : 0;
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Radio(
|
||||
'page_type',
|
||||
NULL,
|
||||
FALSE,
|
||||
array( 'options' => array( 'builder' => 'page_type_builder', 'html' => 'page_type_manual' ),
|
||||
'descriptions' => array( 'builder' => 'page_type_builder_desc', 'html' => 'page_type_manual_custom_desc' ) ),
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
'page_type'
|
||||
) );
|
||||
|
||||
|
||||
if ( $values = $form->values() )
|
||||
/* If this is a database page, redirect to database form */
|
||||
if( isset( static::$pageToDatabaseMap[ Request::i()->id ] ) )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=cms&module=pages&controller=pages&do=form&subnode=1&page_type=' . $values['page_type'] . '&parent=' . \IPS\Request::i()->parent ) );
|
||||
Output::i()->redirect( Url::internal( "app=cms&module=databases&controller=databases&do=form&id=" . static::$pageToDatabaseMap[ Request::i()->id ] ) );
|
||||
}
|
||||
|
||||
/* Display */
|
||||
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'global', 'core', 'admin' )->block( \IPS\Member::loggedIn()->language()->addToStack('content_add_page'), $form, FALSE );
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('content_add_page');
|
||||
parent::form();
|
||||
}
|
||||
|
||||
/**
|
||||
* Permissions
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function permissions() : void
|
||||
{
|
||||
/* If this is a database page, redirect to database permissions */
|
||||
if( isset( static::$pageToDatabaseMap[ Request::i()->id ] ) )
|
||||
{
|
||||
Output::i()->redirect( Url::internal( "app=cms&module=databases&controller=databases&do=permissions&id=" . static::$pageToDatabaseMap[ Request::i()->id ] ) );
|
||||
}
|
||||
|
||||
parent::permissions();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -234,15 +255,21 @@ FILE;
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function delete()
|
||||
protected function delete() : void
|
||||
{
|
||||
if ( isset( \IPS\Request::i()->id ) )
|
||||
/* Database pages cannot be deleted from here */
|
||||
if( isset( static::$pageToDatabaseMap[ Request::i()->id ] ) )
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
\IPS\cms\Pages\Page::deleteCompiled( \IPS\Request::i()->id );
|
||||
Output::i()->error( Member::loggedIn()->language()->addToStack( 'content_acp_err_page_db_delete' ), '3T260/1', 403 );
|
||||
}
|
||||
|
||||
return parent::delete();
|
||||
if ( isset( Request::i()->id ) )
|
||||
{
|
||||
Session::i()->csrfCheck();
|
||||
Page::deleteCompiled( Request::i()->id );
|
||||
}
|
||||
|
||||
parent::delete();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -250,11 +277,11 @@ FILE;
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setAsDefault()
|
||||
protected function setAsDefault() : void
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
\IPS\cms\Pages\Page::load( \IPS\Request::i()->id )->setAsDefault();
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=cms&module=pages&controller=pages" ), 'saved' );
|
||||
Session::i()->csrfCheck();
|
||||
Page::load( Request::i()->id )->setAsDefault();
|
||||
Output::i()->redirect( Url::internal( "app=cms&module=pages&controller=pages" ), 'saved' );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -262,11 +289,11 @@ FILE;
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function toggleDefaultError()
|
||||
protected function toggleDefaultError() : void
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
\IPS\Settings::i()->changeValues( array( 'cms_error_page' => \IPS\Request::i()->id ? \IPS\Request::i()->id : NULL ) );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=cms&module=pages&controller=pages" ), 'saved' );
|
||||
Session::i()->csrfCheck();
|
||||
Settings::i()->changeValues( array( 'cms_error_page' => Request::i()->id ? Request::i()->id : NULL ) );
|
||||
Output::i()->redirect( Url::internal( "app=cms&module=pages&controller=pages" ), 'saved' );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -274,120 +301,128 @@ FILE;
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function search()
|
||||
protected function search() : void
|
||||
{
|
||||
$rows = array();
|
||||
$url = \IPS\Http\Url::internal( "app=cms&module=pages&controller=pages" );
|
||||
$url = Url::internal( "app=cms&module=pages&controller=pages" );
|
||||
|
||||
/* Get results */
|
||||
$folders = \IPS\cms\Pages\Folder::search( 'folder_name' , \IPS\Request::i()->input, 'folder_name' );
|
||||
$pages = \IPS\cms\Pages\Page::search( 'page_seo_name', \IPS\Request::i()->input, 'page_seo_name' );
|
||||
$folders = Folder::search( 'folder_name' , Request::i()->input, 'folder_name' );
|
||||
$pages = Page::search( 'page_seo_name', Request::i()->input, 'page_seo_name' );
|
||||
|
||||
$results = \IPS\cms\Pages\Folder::munge( $folders, $pages );
|
||||
$results = Folder::munge( $folders, $pages );
|
||||
|
||||
/* Convert to HTML */
|
||||
foreach ( $results as $id => $result )
|
||||
{
|
||||
$rows[ $id ] = ( $result instanceof \IPS\cms\Pages\Page ) ? $this->getPageRow( $result, $url ) : $this->getFolderRow( $result, $url );
|
||||
$rows[ $id ] = ( $result instanceof Page ) ? $this->getPageRow( $result, $url ) : $this->getFolderRow( $result, $url );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'trees', 'core' )->rows( $rows, '' );
|
||||
Output::i()->output = Theme::i()->getTemplate( 'trees', 'core' )->rows( $rows, '' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return HTML for a page row
|
||||
*
|
||||
* @param array $page Row data
|
||||
* @param object $url \IPS\Http\Url object
|
||||
* @return string HTML
|
||||
* @param Page $page Row data
|
||||
* @param url $url \IPS\Http\Url object
|
||||
* @return string HTML
|
||||
*/
|
||||
public static function getPageRow( $page, $url )
|
||||
public static function getPageRow( Page $page, Url $url ): string
|
||||
{
|
||||
$badge = NULL;
|
||||
$description = "";
|
||||
|
||||
if ( isset( static::$pageToDatabaseMap[ $page->id ] ) )
|
||||
{
|
||||
$badge = array( 0 => 'style7', 1 => \IPS\Member::loggedIn()->language()->addToStack( 'page_database_display', FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->addToStack('content_db_' . static::$pageToDatabaseMap[ $page->id ] ) ) ) ) );
|
||||
$badge = array( 0 => 'style7', 1 => Member::loggedIn()->language()->addToStack( 'page_database_display', FALSE, array( 'sprintf' => array( Member::loggedIn()->language()->addToStack('content_db_' . static::$pageToDatabaseMap[ $page->id ] ) ) ) ) );
|
||||
|
||||
$description = "<i class='fa-solid fa-triangle-exclamation i-margin-end_icon'></i> " .
|
||||
Member::loggedIn()->language()->addToStack( 'page_database_edit_message', true, array(
|
||||
'sprintf' => array( Url::internal( "app=cms&module=databases&controller=databases&do=form&id=" . static::$pageToDatabaseMap[ $page->id ] ) )
|
||||
) );
|
||||
}
|
||||
return \IPS\Theme::i()->getTemplate( 'trees', 'core' )->row( $url, $page->id, $page->seo_name, false, $page->getButtons( \IPS\Http\Url::internal('app=cms&module=pages&controller=pages'), true ), \IPS\Member::loggedIn()->language()->addToStack( 'num_views_with_number', NULL, array( 'pluralize' => array( $page->views ) ) ), 'file-text-o', NULL, FALSE, NULL, NULL, $badge, FALSE, FALSE, FALSE );
|
||||
return Theme::i()->getTemplate( 'trees', 'core' )->row( $url, $page->id, $page->seo_name, false, $page->getButtons( \IPS\Http\Url::internal('app=cms&module=pages&controller=pages'), true ), Member::loggedIn()->language()->addToStack( 'num_views_with_number', NULL, array( 'pluralize' => array( $page->views ) ) ), 'file-text-o', NULL, FALSE, NULL, NULL, $badge, FALSE, FALSE, FALSE );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Return HTML for a folder row
|
||||
*
|
||||
* @param array $folder Row data
|
||||
* @param object $url \IPS\Http\Url object
|
||||
* @param Folder $folder Row data
|
||||
* @param Url $url \IPS\Http\Url object
|
||||
* @return string HTML
|
||||
*/
|
||||
public static function getFolderRow( $folder, $url )
|
||||
public static function getFolderRow( Folder $folder, Url $url ): string
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'trees', 'core' )->row( $url, $folder->id, $folder->name, true, $folder->getButtons( \IPS\Http\Url::internal('app=cms&module=pages&controller=pages') ), "", 'folder-o', NULL );
|
||||
return Theme::i()->getTemplate( 'trees', 'core' )->row( $url, $folder->id, $folder->name, true, $folder->getButtons( Url::internal('app=cms&module=pages&controller=pages') ), "", 'folder', NULL );
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch rows of folders/pages
|
||||
*
|
||||
* @param int $folderId Parent ID to fetch from
|
||||
* @param int $folderId Parent ID to fetch from
|
||||
* @return array
|
||||
*/
|
||||
public static function getRowsForTree( $folderId=0 )
|
||||
public static function getRowsForTree( int $folderId=0 ) : array
|
||||
{
|
||||
try
|
||||
{
|
||||
if ( $folderId === 0 )
|
||||
{
|
||||
$folders = \IPS\cms\Pages\Folder::roots();
|
||||
$folders = Folder::roots();
|
||||
}
|
||||
else
|
||||
{
|
||||
$folders = \IPS\cms\Pages\Folder::load( $folderId )->children( NULL, NULL, FALSE );
|
||||
$folders = Folder::load( $folderId )->children( NULL, NULL, FALSE );
|
||||
}
|
||||
}
|
||||
catch( \OutOfRangeException $ex )
|
||||
catch( OutOfRangeException $ex )
|
||||
{
|
||||
$folders = array();
|
||||
}
|
||||
|
||||
$pages = \IPS\cms\Pages\Page::getChildren( $folderId );
|
||||
$pages = Page::getChildren( $folderId );
|
||||
|
||||
return \IPS\cms\Pages\Folder::munge( $folders, $pages );
|
||||
return Folder::munge( $folders, $pages );
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect after save
|
||||
*
|
||||
* @param \IPS\Node\Model $old A clone of the node as it was before or NULL if this is a creation
|
||||
* @param \IPS\Node\Model $new The node now
|
||||
* @param string $lastUsedTab The tab last used in the form
|
||||
* @return void
|
||||
* @param Model|null $old A clone of the node as it was before or NULL if this is a creation
|
||||
* @param Model $new The node now
|
||||
* @param string|bool $lastUsedTab The tab last used in the form
|
||||
* @return void
|
||||
*/
|
||||
protected function _afterSave( ?\IPS\Node\Model $old, \IPS\Node\Model $new, $lastUsedTab = FALSE )
|
||||
protected function _afterSave( ?Model $old, Model $new, mixed $lastUsedTab=FALSE ): void
|
||||
{
|
||||
/* Is there a default page in the folder? */
|
||||
try
|
||||
{
|
||||
$existingDefault = \IPS\Db::i()->select( 'page_id', 'cms_pages', array( 'page_folder_id=? and page_default=? and page_id <> ?', $new->folder_id, 1, $new->id ) )->first();
|
||||
$existingDefault = Db::i()->select( 'page_id', 'cms_pages', array( 'page_folder_id=? and page_default=? and page_id <> ?', $new->folder_id, 1, $new->id ) )->first();
|
||||
|
||||
/* If this page was the default in a folder, and it was moved to a new folder that already has a default, we need to unset the
|
||||
default page flag or there will be two defaults in the destination folder */
|
||||
if( $old !== NULL AND $old->folder_id != $new->folder_id AND $old->default )
|
||||
{
|
||||
\IPS\Db::i()->update( 'cms_pages', array( 'page_default' => 0 ), array( 'page_id=?', $new->id ) );
|
||||
Db::i()->update( 'cms_pages', array( 'page_default' => 0 ), array( 'page_id=?', $new->id ) );
|
||||
|
||||
\IPS\cms\Pages\Page::buildPageUrlStore();
|
||||
Page::buildPageUrlStore();
|
||||
}
|
||||
}
|
||||
catch( \UnderflowException $e )
|
||||
catch( UnderflowException $e )
|
||||
{
|
||||
/* No default found in destination folder, make this the default */
|
||||
\IPS\Db::i()->update( 'cms_pages', array( 'page_default' => 1 ), array( 'page_id=?', $new->id ) );
|
||||
Db::i()->update( 'cms_pages', array( 'page_default' => 1 ), array( 'page_id=?', $new->id ) );
|
||||
|
||||
\IPS\cms\Pages\Page::buildPageUrlStore();
|
||||
Page::buildPageUrlStore();
|
||||
}
|
||||
|
||||
/* If page filename changes or the folder ID changes, we need to clear front navigation cache*/
|
||||
if( $old !== NULL AND ( $old->folder_id != $new->folder_id OR $old->seo_name != $new->seo_name ) )
|
||||
{
|
||||
unset( \IPS\Data\Store::i()->pages_page_urls );
|
||||
unset( Store::i()->pages_page_urls );
|
||||
}
|
||||
|
||||
parent::_afterSave( $old, $new, $lastUsedTab );
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @brief Ajax only methods
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
@@ -12,25 +13,37 @@
|
||||
namespace IPS\cms\modules\front\database;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\cms\Databases;
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\Http\Url\Friendly;
|
||||
use IPS\Member;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
use IPS\cms\Records;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax only methods
|
||||
*/
|
||||
class _ajax extends \IPS\Dispatcher\Controller
|
||||
class ajax extends Controller
|
||||
{
|
||||
/**
|
||||
* Return a FURL
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function makeFurl()
|
||||
protected function makeFurl() : void
|
||||
{
|
||||
return \IPS\Output::i()->json( array( 'slug' => \IPS\Http\Url\Friendly::seoTitle( \IPS\Request::i()->slug ) ) );
|
||||
Output::i()->json( array( 'slug' => Friendly::seoTitle( Request::i()->slug ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -38,19 +51,21 @@ class _ajax extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function findRecord()
|
||||
public function findRecord() : void
|
||||
{
|
||||
$results = array();
|
||||
$database = \IPS\cms\Databases::load( \IPS\Request::i()->id );
|
||||
$input = mb_strtolower( \IPS\Request::i()->input );
|
||||
$database = Databases::load( Request::i()->id );
|
||||
$input = mb_strtolower( Request::i()->input );
|
||||
$field = "field_" . $database->field_title;
|
||||
|
||||
/* @var Records $class */
|
||||
$class = '\IPS\cms\Records' . $database->id;
|
||||
$category = '';
|
||||
|
||||
$where = array( $field . " LIKE CONCAT('%', ?, '%')" );
|
||||
$binds = array( $input );
|
||||
|
||||
foreach ( \IPS\Db::i()->select( '*', 'cms_custom_database_' . $database->id, array_merge( array( implode( ' OR ', $where ) ), $binds ), 'LENGTH(' . $field . ') ASC', array( 0, 20 ) ) as $row )
|
||||
foreach ( Db::i()->select( '*', 'cms_custom_database_' . $database->id, array_merge( array( implode( ' OR ', $where ) ), $binds ), 'LENGTH(' . $field . ') ASC', array( 0, 20 ) ) as $row )
|
||||
{
|
||||
$record = $class::constructFromData( $row );
|
||||
|
||||
@@ -61,18 +76,18 @@ class _ajax extends \IPS\Dispatcher\Controller
|
||||
|
||||
if ( $database->use_categories )
|
||||
{
|
||||
$category = \IPS\Member::loggedIn()->language()->addToStack( 'cms_autocomplete_category', FALSE, array( 'sprintf' => array( $record->container()->_title ) ) );
|
||||
$category = Member::loggedIn()->language()->addToStack( 'cms_autocomplete_category', FALSE, array( 'sprintf' => array( $record->container()->_title ) ) );
|
||||
}
|
||||
|
||||
$results[] = array(
|
||||
'id' => $record->_id,
|
||||
'value' => $record->_title,
|
||||
'category' => $category,
|
||||
'date' => \IPS\DateTime::ts( $record->record_publish_date )->html(),
|
||||
'date' => DateTime::ts( $record->record_publish_date )->html(),
|
||||
);
|
||||
}
|
||||
|
||||
\IPS\Output::i()->json( $results );
|
||||
Output::i()->json( $results );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @brief [Database] Category Controller
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
@@ -11,31 +12,67 @@
|
||||
namespace IPS\cms\modules\front\database;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DateInterval;
|
||||
use Exception;
|
||||
use IPS\cms\Categories;
|
||||
use IPS\cms\Databases;
|
||||
use IPS\cms\Databases\Controller;
|
||||
use IPS\cms\Databases\Dispatcher;
|
||||
use IPS\cms\Fields;
|
||||
use IPS\cms\Pages\Page;
|
||||
use IPS\cms\Records;
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\File;
|
||||
use IPS\GeoLocation;
|
||||
use IPS\Helpers\Table\Content;
|
||||
use IPS\Member;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
use IPS\Session;
|
||||
use IPS\Settings;
|
||||
use IPS\Theme;
|
||||
use IPS\Xml\Rss;
|
||||
use OutOfRangeException;
|
||||
use function count;
|
||||
use function defined;
|
||||
use function in_array;
|
||||
use function intval;
|
||||
use function is_array;
|
||||
use function is_bool;
|
||||
use const IPS\Helpers\Table\SEARCH_BOOL;
|
||||
use const IPS\Helpers\Table\SEARCH_CHECKBOX;
|
||||
use const IPS\Helpers\Table\SEARCH_DATE_RANGE;
|
||||
use const IPS\Helpers\Table\SEARCH_MEMBER;
|
||||
use const IPS\Helpers\Table\SEARCH_NUMERIC_TEXT;
|
||||
use const IPS\Helpers\Table\SEARCH_SELECT;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* page
|
||||
*/
|
||||
class _category extends \IPS\cms\Databases\Controller
|
||||
class category extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Store any active filters for this view
|
||||
*
|
||||
* @param array
|
||||
* @var array
|
||||
*/
|
||||
static public $activeFilters = array();
|
||||
static public array $activeFilters = array();
|
||||
|
||||
/**
|
||||
* Determine which method to load
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function manage()
|
||||
public function manage() : void
|
||||
{
|
||||
$this->view();
|
||||
}
|
||||
@@ -45,22 +82,23 @@ class _category extends \IPS\cms\Databases\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function clearFilters()
|
||||
public function clearFilters() : void
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
$catClass = 'IPS\cms\Categories' . \IPS\cms\Databases\Dispatcher::i()->databaseId;
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
/* @var Categories $catClass */
|
||||
$catClass = 'IPS\cms\Categories' . Dispatcher::i()->databaseId;
|
||||
|
||||
try
|
||||
{
|
||||
$category = $catClass::loadAndCheckPerms( \IPS\cms\Databases\Dispatcher::i()->categoryId );
|
||||
$category = $catClass::loadAndCheckPerms( Dispatcher::i()->categoryId );
|
||||
$category->saveFilterCookie( FALSE );
|
||||
|
||||
\IPS\Output::i()->redirect( $category->url(), 'cms_filters_cleared' );
|
||||
Output::i()->redirect( $category->url(), 'cms_filters_cleared' );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2T254/1', 403, '' );
|
||||
Output::i()->error( 'node_error', '2T254/1', 403, '' );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,41 +107,40 @@ class _category extends \IPS\cms\Databases\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function view()
|
||||
public function view() : void
|
||||
{
|
||||
/* @var Categories $catClass
|
||||
* @var Fields $fieldClass */
|
||||
$category = NULL;
|
||||
$fieldClass = 'IPS\cms\Fields' . \IPS\cms\Databases\Dispatcher::i()->databaseId;
|
||||
$catClass = 'IPS\cms\Categories' . \IPS\cms\Databases\Dispatcher::i()->databaseId;
|
||||
$database = \IPS\cms\Databases::load( \IPS\cms\Databases\Dispatcher::i()->databaseId );
|
||||
$fieldClass = 'IPS\cms\Fields' . Dispatcher::i()->databaseId;
|
||||
$catClass = 'IPS\cms\Categories' . Dispatcher::i()->databaseId;
|
||||
$database = Databases::load( Dispatcher::i()->databaseId );
|
||||
$breadcrumbs = NULL;
|
||||
|
||||
try
|
||||
{
|
||||
$category = $catClass::loadAndCheckPerms( \IPS\cms\Databases\Dispatcher::i()->categoryId );
|
||||
$category = $catClass::loadAndCheckPerms( Dispatcher::i()->categoryId );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2T254/2', 403, '' );
|
||||
Output::i()->error( 'node_error', '2T254/2', 403, '' );
|
||||
}
|
||||
|
||||
|
||||
$customFields = $fieldClass::data( 'view', $category, $fieldClass::FIELD_SKIP_TITLE_CONTENT );
|
||||
|
||||
if ( ! $database->use_categories )
|
||||
{
|
||||
$breadcrumbs = \IPS\Output::i()->breadcrumb;
|
||||
$breadcrumbs = Output::i()->breadcrumb;
|
||||
}
|
||||
|
||||
$RecordsClass = $category::$contentItemClass;
|
||||
|
||||
$recordsClass = $category::$contentItemClass;
|
||||
|
||||
/* AdvancedSearch can wipe out the checked box as it is looking for _checkbox. Note to self in 4.5, rewrite the filter widget to avoid using advancedSearch :/ */
|
||||
if ( ! isset( \IPS\Request::i()->cms_record_i_started_checkbox ) and isset( \IPS\Request::i()->cms_record_i_started ) and \IPS\Request::i()->cms_record_i_started )
|
||||
if ( ! isset( Request::i()->cms_record_i_started_checkbox ) and isset( Request::i()->cms_record_i_started ) and Request::i()->cms_record_i_started )
|
||||
{
|
||||
\IPS\Request::i()->cms_record_i_started_checkbox = \IPS\Request::i()->cms_record_i_started;
|
||||
Request::i()->cms_record_i_started_checkbox = Request::i()->cms_record_i_started;
|
||||
}
|
||||
|
||||
/* we need this language later (and in Widgets\DatabaseFilters which is executed just before output) */
|
||||
\IPS\Member::loggedIn()->language()->words['cms_record_i_started'] = \IPS\Member::loggedIn()->language()->addToStack( 'cms_record_i_started_sprintf', FALSE, array( 'sprintf' => $database->recordWord() ) );
|
||||
|
||||
/* Check cookie */
|
||||
$where = array();
|
||||
$cookie = $category->getFilterCookie();
|
||||
@@ -112,117 +149,50 @@ class _category extends \IPS\cms\Databases\Controller
|
||||
{
|
||||
foreach( $cookie as $f => $v )
|
||||
{
|
||||
if ( $f == 'cms_record_i_started' and \IPS\Member::loggedIn()->member_id )
|
||||
if( $f == 'cms_record_i_started' and Member::loggedIn()->member_id )
|
||||
{
|
||||
$where[] = 'cms_custom_database_' . $database->id . '.member_id=' . \IPS\Member::loggedIn()->member_id;
|
||||
|
||||
/* FilterMessage template only accepts \IPS\cms\Fields */
|
||||
$field = new \IPS\cms\Fields;
|
||||
$field = new Fields;
|
||||
$field->id = 'cms_record_i_started';
|
||||
|
||||
\IPS\Member::loggedIn()->language()->words['content_field_cms_record_i_started'] = \IPS\Member::loggedIn()->language()->addToStack( 'cms_record_i_started_sprintf', FALSE, array( 'sprintf' => $database->recordWord() ) );
|
||||
|
||||
static::$activeFilters['cms_record_i_started'] = array( 'field' => $field, 'value' => \IPS\Member::loggedIn()->language()->addToStack('content_field_cms_record_i_started_on') );
|
||||
continue;
|
||||
|
||||
Member::loggedIn()->language()->words['content_field_cms_record_i_started'] = Member::loggedIn()->language()->addToStack( 'cms_record_i_started_sprintf', FALSE, array( 'sprintf' => $database->recordWord() ) );
|
||||
|
||||
static::$activeFilters['cms_record_i_started'] = array( 'field' => $field, 'value' => Member::loggedIn()->language()->addToStack('content_field_cms_record_i_started_on') );
|
||||
}
|
||||
|
||||
$k = 'content_field_' . $f;
|
||||
|
||||
$displayValue = $customFields[ $f ]->displayValue( $v );
|
||||
$concat = ',';
|
||||
|
||||
if ( $customFields[ $f ]->type === 'Member' )
|
||||
else
|
||||
{
|
||||
if ( ! empty( $v ) )
|
||||
$displayValue = $customFields[ $f ]->displayValue( $v );
|
||||
|
||||
if ( $customFields[ $f ]->type === 'Member' )
|
||||
{
|
||||
$newValue = array();
|
||||
$newDisplayValue = array();
|
||||
$concat = '\n';
|
||||
|
||||
if ( \is_array( $v ) )
|
||||
if ( ! empty( $v ) )
|
||||
{
|
||||
foreach( $v as $m )
|
||||
$newDisplayValue = array();
|
||||
$concat = '\n';
|
||||
|
||||
if ( is_array( $v ) )
|
||||
{
|
||||
$member = \IPS\Member::load( $m );
|
||||
$newValue[] = $member->member_id;
|
||||
$newDisplayValue[] = $member->name;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$member = \IPS\Member::load( $v );
|
||||
$newValue[] = $member->member_id;
|
||||
$newDisplayValue[] = $member->name;
|
||||
}
|
||||
|
||||
$displayValue = implode( ', ', $newDisplayValue );
|
||||
$v = $newValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The content_field_x can be an empty array from the member form */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $customFields[ $f ] ) and !isset( \IPS\Request::i()->$k ) and $v !== '___any___' )
|
||||
{
|
||||
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'] );
|
||||
|
||||
if ( $start or $end )
|
||||
{
|
||||
$where[] = array( '( ' . mb_substr( $k, 8 ) . ' BETWEEN ' . $start . ' AND ' . $end . ' )' );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$like = array();
|
||||
foreach( $v as $val )
|
||||
{
|
||||
if ( $val === 0 or ! empty( $val ) )
|
||||
foreach( $v as $m )
|
||||
{
|
||||
$like[] = "CONCAT( '{$concat}', " . mb_substr( $k, 8 ) . ", '{$concat}') LIKE '%{$concat}" . \IPS\Db::i()->real_escape_string( $val ) . "{$concat}%'";
|
||||
$member = Member::load( $m );
|
||||
$newDisplayValue[] = $member->name;
|
||||
}
|
||||
}
|
||||
|
||||
$where[] = array( '( ' . \IPS\Db::i()->in( mb_substr( $k, 8 ), $v ) . ( \count( $like ) ? " OR (" . implode( ' OR ', $like ) . ') )' : ')' ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( \is_bool( $v ) )
|
||||
{
|
||||
/* YesNo fields are false or true */
|
||||
if ( $v === false )
|
||||
{
|
||||
$where[] = array( '(' . mb_substr( $k, 8 ) . ' IS NULL or ' . mb_substr( $k, 8 ) . '=0)' );
|
||||
}
|
||||
else
|
||||
{
|
||||
$where[] = array( mb_substr( $k, 8 ) . "=1" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( $v !== 0 and ! $v )
|
||||
{
|
||||
$where[] = array( mb_substr( $k, 8 ) . " IS NULL" );
|
||||
}
|
||||
else
|
||||
{
|
||||
$where[] = array( mb_substr( $k, 8 ) . "=?", $v );
|
||||
$member = Member::load( $v );
|
||||
$newDisplayValue[] = $member->name;
|
||||
}
|
||||
|
||||
$displayValue = implode( ', ', $newDisplayValue );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static::$activeFilters[ $f ] = array( 'field' => $customFields[ $f ], 'value' => $displayValue );
|
||||
}
|
||||
}
|
||||
|
||||
$where = $category->buildWhereFromCookie( $cookie );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -235,68 +205,97 @@ class _category extends \IPS\cms\Databases\Controller
|
||||
$names = NULL;
|
||||
|
||||
/* We need to homogenize data, we store IDs, but the Form helper needs objects or names */
|
||||
if ( isset( \IPS\Request::i()->$requestField ) and ! isset( \IPS\Request::i()->$didWeJustHitSubmit ) )
|
||||
if ( isset( Request::i()->$requestField ) and ! isset( Request::i()->$didWeJustHitSubmit ) )
|
||||
{
|
||||
/* The URL alwyas uses IDs, so map these to names */
|
||||
$names = array_map( function( $id )
|
||||
{
|
||||
return \IPS\Member::load( $id )->name;
|
||||
}, ( \is_array( \IPS\Request::i()->$requestField ) ? \IPS\Request::i()->$requestField : array( \IPS\Request::i()->$requestField ) ) );
|
||||
return Member::load( $id )->name;
|
||||
}, ( is_array( Request::i()->$requestField ) ? Request::i()->$requestField : array( Request::i()->$requestField ) ) );
|
||||
}
|
||||
else if ( isset( \IPS\Request::i()->$requestField ) )
|
||||
else if ( isset( Request::i()->$requestField ) )
|
||||
{
|
||||
/* The names are foo\nbar so already names */
|
||||
$names = explode( "\n", \IPS\Request::i()->$requestField );
|
||||
$names = explode( "\n", Request::i()->$requestField );
|
||||
}
|
||||
|
||||
if ( $names !== NULL )
|
||||
{
|
||||
\IPS\Request::i()->$requestField = $names;
|
||||
Request::i()->$requestField = $names;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the meta image */
|
||||
if( $category->image )
|
||||
{
|
||||
try
|
||||
{
|
||||
Output::i()->metaTags['og:image'] = File::get( 'cms_Categories', $category->image )->url;
|
||||
}
|
||||
catch( OutOfRangeException ){}
|
||||
}
|
||||
|
||||
if ( ( $category->hasChildren() AND $category->show_records ) OR ! $category->hasChildren() )
|
||||
{
|
||||
if ( ! \count( $where ) )
|
||||
if ( ! count( $where ) )
|
||||
{
|
||||
$where = NULL;
|
||||
}
|
||||
|
||||
if( \IPS\Request::i()->advanced_search_submitted )
|
||||
if( Request::i()->advanced_search_submitted )
|
||||
{
|
||||
\IPS\Request::i()->csrfKey = \IPS\Session::i()->csrfKey;
|
||||
Request::i()->csrfKey = Session::i()->csrfKey;
|
||||
}
|
||||
|
||||
$table = new \IPS\Helpers\Table\Content( 'IPS\cms\Records' . \IPS\cms\Databases\Dispatcher::i()->databaseId, $category->url(), $where, $category, NULL, 'read', isset( \IPS\Request::i()->rss ) ? FALSE : TRUE );
|
||||
|
||||
/* @var Records $recordsClass */
|
||||
$table = new Content( 'IPS\cms\Records' . Dispatcher::i()->databaseId, $category->url(), $where, $category, NULL, 'read', !isset(Request::i()->rss));
|
||||
$table->tableTemplate = array( \IPS\cms\Theme::i()->getTemplate( $category->_template_listing, 'cms', 'database' ), 'categoryTable' );
|
||||
$table->rowsTemplate = array( \IPS\cms\Theme::i()->getTemplate( $category->_template_listing, 'cms', 'database' ), 'recordRow' );
|
||||
$table->baseUrl = $table->baseUrl->setQueryString( 'd', \IPS\cms\Databases\Dispatcher::i()->databaseId );
|
||||
$table->baseUrl = $table->baseUrl->setQueryString( 'd', Dispatcher::i()->databaseId );
|
||||
|
||||
/* Does the category have a custom layout? */
|
||||
if( $category->template_listing == 0 )
|
||||
{
|
||||
$table->extra = [ 'layout' => $database->display_settings['listing']['layout'] ];
|
||||
}
|
||||
else
|
||||
{
|
||||
if( $displaySettings = $category->display_settings )
|
||||
{
|
||||
$table->extra = [ 'layout' => $displaySettings['layout'] ];
|
||||
}
|
||||
else
|
||||
{
|
||||
$table->extra = [ 'layout' => 'table' ];
|
||||
}
|
||||
}
|
||||
|
||||
$table->hover = TRUE;
|
||||
$table->sortBy = ( isset( \IPS\Request::i()->sortby ) ) ? \IPS\Request::i()->sortby : ( $database->field_sort ? $RecordsClass::$databaseTable . '.' . $RecordsClass::$databasePrefix . $database->field_sort : 'record_last_comment' );
|
||||
$table->sortDirection = ( isset( \IPS\Request::i()->sortdirection ) ) ? \IPS\Request::i()->sortdirection : ( $database->field_direction ? $database->field_direction : 'desc' );
|
||||
$table->sortBy = ( isset( Request::i()->sortby ) ) ? Request::i()->sortby : ( $database->field_sort ? $recordsClass::$databaseTable . '.' . $recordsClass::$databasePrefix . $database->field_sort : 'record_last_comment' );
|
||||
$table->sortDirection = ( isset( Request::i()->sortdirection ) ) ? Request::i()->sortdirection : ( $database->field_direction ? $database->field_direction : 'desc' );
|
||||
if ( $database->field_sort )
|
||||
{
|
||||
$table->defaultSortBy = $RecordsClass::$databasePrefix . $database->field_sort;
|
||||
$table->defaultSortBy = $recordsClass::$databasePrefix . $database->field_sort;
|
||||
$table->defaultSortDirection = $database->field_direction;
|
||||
}
|
||||
$table->limit = $database->field_perpage ? $database->field_perpage : 25;
|
||||
$table->title = \IPS\Member::loggedIn()->language()->addToStack( $database->use_categories ? 'x_records_in_this_category' : 'x_records' , FALSE, array( 'sprintf' => array( $category->_items, $database->recordWord( $category->_items ) ) ) );
|
||||
$table->title = Member::loggedIn()->language()->addToStack( $database->use_categories ? 'x_records_in_this_category' : 'x_records' , FALSE, array( 'sprintf' => array( $category->_items, $database->recordWord( $category->_items ) ) ) );
|
||||
|
||||
/* Set up sort fields to allow sorting numerically or by date */
|
||||
$sortFields = $customFields;
|
||||
$sortFields[ $database->field_title ] = $fieldClass::load( $database->field_title );
|
||||
foreach( $sortFields as $id => $obj )
|
||||
{
|
||||
if ( $table->sortBy == $RecordsClass::$databaseTable . '.' . 'field_' . $id OR $table->sortBy == 'field_' . $id )
|
||||
if ( $table->sortBy == $recordsClass::$databaseTable . '.' . 'field_' . $id OR $table->sortBy == 'field_' . $id )
|
||||
{
|
||||
if ( \in_array( $obj->type, array( 'Number', 'Date' ) ) )
|
||||
if ( in_array( $obj->type, array( 'Number', 'Date' ) ) )
|
||||
{
|
||||
$fieldName = $table->sortBy;
|
||||
if ( mb_strstr( $table->sortBy, '.' ) )
|
||||
{
|
||||
list( $db, $fieldName ) = explode( '.', $table->sortBy );
|
||||
[ $db, $fieldName ] = explode( '.', $table->sortBy );
|
||||
}
|
||||
|
||||
$table->sortOptions[ $fieldName ] = 'CAST(`field_' . $id . '` AS UNSIGNED)';
|
||||
@@ -308,7 +307,7 @@ class _category extends \IPS\cms\Databases\Controller
|
||||
/* Make sure table doesn't add breadcrumbs if we're not using categories */
|
||||
if ( ! $database->use_categories )
|
||||
{
|
||||
\IPS\Output::i()->breadcrumb = $breadcrumbs;
|
||||
Output::i()->breadcrumb = $breadcrumbs;
|
||||
}
|
||||
|
||||
/* Custom Search */
|
||||
@@ -331,9 +330,9 @@ class _category extends \IPS\cms\Databases\Controller
|
||||
'last_90_days' => 'last_90_days',
|
||||
);
|
||||
|
||||
if ( \IPS\Member::loggedIn()->member_id AND \IPS\Member::loggedIn()->last_visit )
|
||||
if ( Member::loggedIn()->member_id AND Member::loggedIn()->last_visit )
|
||||
{
|
||||
$timeFrameOptions['since_last_visit'] = \IPS\Member::loggedIn()->language()->addToStack('since_last_visit', FALSE, array( 'sprintf' => array( \IPS\DateTime::ts( \IPS\Member::loggedIn()->last_visit ) ) ) );
|
||||
$timeFrameOptions['since_last_visit'] = Member::loggedIn()->language()->addToStack('since_last_visit', FALSE, array( 'sprintf' => array( DateTime::ts( (int) Member::loggedIn()->last_visit ) ) ) );
|
||||
}
|
||||
|
||||
$sortBy = array(
|
||||
@@ -348,7 +347,7 @@ class _category extends \IPS\cms\Databases\Controller
|
||||
$table->sortOptions = array_unique( array_merge( $table->sortOptions, array_combine( array_keys( $sortBy ), array_keys( $sortBy ) ) ) );
|
||||
|
||||
/* To avoid confusion, label 'updated' as 'Recently Updated' as last comment */
|
||||
\IPS\Member::loggedIn()->language()->words[ $table->langPrefix . 'sort_updated' ] = \IPS\Member::loggedIn()->language()->addToStack('content_record_last_comment');
|
||||
Member::loggedIn()->language()->words[ $table->langPrefix . 'sort_updated' ] = Member::loggedIn()->language()->addToStack('content_record_last_comment');
|
||||
|
||||
if ( !isset( $sortBy[ $database->field_sort ] ) )
|
||||
{
|
||||
@@ -357,17 +356,17 @@ class _category extends \IPS\cms\Databases\Controller
|
||||
case 'primary_id_field':
|
||||
$sortBy[ $database->field_sort ] = 'database_field__id';
|
||||
$table->sortOptions['database_field__id'] = $database->field_sort;
|
||||
\IPS\Member::loggedIn()->language()->words['sort_database_field__id'] = \IPS\Member::loggedIn()->language()->addToStack('database_field__id');
|
||||
Member::loggedIn()->language()->words['sort_database_field__id'] = Member::loggedIn()->language()->addToStack('database_field__id');
|
||||
break;
|
||||
case 'member_id':
|
||||
$sortBy[ $database->field_sort ] = 'database_field__member';
|
||||
$table->sortOptions['database_field__member'] = $database->field_sort;
|
||||
\IPS\Member::loggedIn()->language()->words['sort_database_field__member'] = \IPS\Member::loggedIn()->language()->addToStack('database_field__member');
|
||||
Member::loggedIn()->language()->words['sort_database_field__member'] = Member::loggedIn()->language()->addToStack('database_field__member');
|
||||
break;
|
||||
case 'record_rating':
|
||||
$sortBy[ $database->field_sort ] = 'database_field__rating';
|
||||
$table->sortOptions['rating'] = $database->field_sort;
|
||||
\IPS\Member::loggedIn()->language()->words['sort_database_field__rating'] = \IPS\Member::loggedIn()->language()->addToStack('database_field__rating');
|
||||
Member::loggedIn()->language()->words['sort_database_field__rating'] = Member::loggedIn()->language()->addToStack('database_field__rating');
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -393,64 +392,64 @@ class _category extends \IPS\cms\Databases\Controller
|
||||
{
|
||||
if ( $database->field_title !== mb_substr( $database->field_sort, 6 ) )
|
||||
{
|
||||
$sortBy[ $database->field_sort ] = \IPS\Member::loggedIn()->language()->addToStack( 'content_field_' . mb_substr( $database->field_sort, 6 ) );
|
||||
$sortBy[ $database->field_sort ] = Member::loggedIn()->language()->addToStack( 'content_field_' . mb_substr( $database->field_sort, 6 ) );
|
||||
$table->sortOptions[ $database->field_sort ] = $database->field_sort;
|
||||
}
|
||||
}
|
||||
|
||||
$table->advancedSearch = array(
|
||||
'record_type' => array( \IPS\Helpers\Table\SEARCH_SELECT, array( 'options' => $filterOptions ) ),
|
||||
'sort_by' => array( \IPS\Helpers\Table\SEARCH_SELECT, array( 'options' => $sortBy ) ),
|
||||
'sort_direction' => array( \IPS\Helpers\Table\SEARCH_SELECT, array( 'options' => array(
|
||||
'record_type' => array( SEARCH_SELECT, array( 'options' => $filterOptions ) ),
|
||||
'sort_by' => array( SEARCH_SELECT, array( 'options' => $sortBy ) ),
|
||||
'sort_direction' => array( SEARCH_SELECT, array( 'options' => array(
|
||||
'asc' => 'asc',
|
||||
'desc' => 'desc',
|
||||
) )
|
||||
),
|
||||
'time_frame' => array( \IPS\Helpers\Table\SEARCH_SELECT, array( 'options' => $timeFrameOptions ) ),
|
||||
'cms_record_i_started' => array( \IPS\Helpers\Table\SEARCH_CHECKBOX, array() ),
|
||||
'time_frame' => array( SEARCH_SELECT, array( 'options' => $timeFrameOptions ) ),
|
||||
'cms_record_i_started' => array( SEARCH_CHECKBOX, array() ),
|
||||
);
|
||||
|
||||
foreach( $customFields as $obj )
|
||||
{
|
||||
if ( $obj->filter )
|
||||
{
|
||||
\IPS\Member::loggedIn()->language()->words['content_field_' . $obj->id ] = $obj->_title;
|
||||
if ( \in_array( $obj->type, array( 'Date', 'DateRange' ) ) )
|
||||
Member::loggedIn()->language()->words['content_field_' . $obj->id ] = $obj->_title;
|
||||
if ( in_array( $obj->type, array( 'Date', 'DateRange' ) ) )
|
||||
{
|
||||
$table->advancedSearch[ 'content_field_' . $obj->id ] = array( \IPS\Helpers\Table\SEARCH_DATE_RANGE, array( 'noDefault' => true ) );
|
||||
$table->advancedSearch[ 'content_field_' . $obj->id ] = array( SEARCH_DATE_RANGE, array( 'noDefault' => true ) );
|
||||
}
|
||||
else if ( $obj->type == 'Number' )
|
||||
{
|
||||
$table->advancedSearch[ 'content_field_' . $obj->id ] = array( \IPS\Helpers\Table\SEARCH_NUMERIC_TEXT, array( 'noDefault' => true ) );
|
||||
$table->advancedSearch[ 'content_field_' . $obj->id ] = array( SEARCH_NUMERIC_TEXT, array( 'noDefault' => true ) );
|
||||
}
|
||||
else if ( $obj->type == 'YesNo' )
|
||||
{
|
||||
$table->advancedSearch[ 'content_field_' . $obj->id ] = array( \IPS\Helpers\Table\SEARCH_BOOL, array( 'noDefault' => true ) );
|
||||
$table->advancedSearch[ 'content_field_' . $obj->id ] = array( SEARCH_BOOL, array( 'noDefault' => true ) );
|
||||
}
|
||||
else if ( $obj->type == 'Member' )
|
||||
{
|
||||
/* Don't show this on the custom modal form because you cannot have two autocompletes with the same name on the same page, and the fix is more invasive than the value of this feature on the modal.
|
||||
The purpose of this is to show in the sidebar filter form */
|
||||
if ( ! isset( \IPS\Request::i()->advancedSearchForm ) )
|
||||
if ( ! isset( Request::i()->advancedSearchForm ) )
|
||||
{
|
||||
$table->advancedSearch[ 'content_field_' . $obj->id ] = array( \IPS\Helpers\Table\SEARCH_MEMBER, array( 'noDefault' => true, 'multiple' => NULL ) );
|
||||
$table->advancedSearch[ 'content_field_' . $obj->id ] = array( SEARCH_MEMBER, array( 'noDefault' => true, 'multiple' => NULL ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$table->advancedSearch[ 'content_field_' . $obj->id ] = array( \IPS\Helpers\Table\SEARCH_SELECT, array( 'options' => $obj->extra, 'multiple' => TRUE, 'noDefault' => true ) );
|
||||
$table->advancedSearch[ 'content_field_' . $obj->id ] = array( SEARCH_SELECT, array( 'options' => $obj->extra, 'multiple' => TRUE, 'noDefault' => true ) );
|
||||
}
|
||||
|
||||
$table->advancedSearch['sort_by'][1]['options']['field_' . $obj->id ] = 'content_field_' . $obj->id;
|
||||
}
|
||||
|
||||
if ( \in_array( $obj->type, array( 'Date', 'DateRange', 'Number' ) ) )
|
||||
if ( in_array( $obj->type, array( 'Date', 'DateRange', 'Number' ) ) )
|
||||
{
|
||||
$table->sortOptions[ 'field_' . $obj->id ] = 'CAST(`field_' . $obj->id . '` AS UNSIGNED)';
|
||||
}
|
||||
else
|
||||
{
|
||||
$table->sortOptions[ 'field_' . $obj->id ] = isset( $table->sortOptions[ 'field_' . $obj->id ] ) ? $table->sortOptions[ 'field_' . $obj->id ] : 'field_' . $obj->id;
|
||||
$table->sortOptions[ 'field_' . $obj->id ] = $table->sortOptions['field_' . $obj->id] ?? 'field_' . $obj->id;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -467,7 +466,7 @@ class _category extends \IPS\cms\Databases\Controller
|
||||
|
||||
if ( $customFields[ $key ]->type === 'Member' )
|
||||
{
|
||||
if ( \is_array( $v ) and \count( $v ) )
|
||||
if ( is_array( $v ) and count( $v ) )
|
||||
{
|
||||
$newValue = array();
|
||||
$newDisplayValue = array();
|
||||
@@ -475,7 +474,7 @@ class _category extends \IPS\cms\Databases\Controller
|
||||
|
||||
foreach( $v as $member )
|
||||
{
|
||||
if ( $member instanceof \IPS\Member )
|
||||
if ( $member instanceof Member )
|
||||
{
|
||||
$newDisplayValue[] = $member->name;
|
||||
$newValue[] = $member->member_id;
|
||||
@@ -492,12 +491,12 @@ class _category extends \IPS\cms\Databases\Controller
|
||||
}
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
@@ -511,18 +510,25 @@ class _category extends \IPS\cms\Databases\Controller
|
||||
{
|
||||
if ( $val === 0 or ! empty( $val ) )
|
||||
{
|
||||
$like[] = "CONCAT( '{$concat}', " . mb_substr( $k, 8 ) . ", '{$concat}') LIKE '%{$concat}" . \IPS\Db::i()->real_escape_string( $val ) . "{$concat}%'";
|
||||
$like[] = $val;
|
||||
}
|
||||
}
|
||||
|
||||
$table->where[] = array( '( ' . \IPS\Db::i()->in( mb_substr( $k, 8 ), $v ) . ( \count( $like ) ? " OR (" . implode( ' OR ', $like ) . ') )' : ')' ) );
|
||||
|
||||
if( $customFields[ $key ]->default_value and in_array( $customFields[ $key ]->default_value, $v ) )
|
||||
{
|
||||
$table->where[] = array( "( " . mb_substr( $k, 8 ) . " IS NULL OR " . Db::i()->findInSet( mb_substr( $k, 8 ), $like ) . ")" );
|
||||
}
|
||||
else
|
||||
{
|
||||
$table->where[] = array( Db::i()->findInSet( mb_substr( $k, 8 ), $like ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( $v !== '___any___' )
|
||||
{
|
||||
if ( \is_bool( $v ) )
|
||||
if ( is_bool( $v ) )
|
||||
{
|
||||
/* YesNo fields are false or true */
|
||||
if ( $v === false )
|
||||
@@ -548,13 +554,13 @@ class _category extends \IPS\cms\Databases\Controller
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\cms\modules\front\database\category::$activeFilters[ $key ] = array( 'field' => $customFields[ $key ], 'value' => $displayValue );
|
||||
category::$activeFilters[ $key ] = array( 'field' => $customFields[ $key ], 'value' => $displayValue );
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $values['cms_record_i_started'] ) and $values['cms_record_i_started'] and \IPS\Member::loggedIn()->member_id )
|
||||
if ( isset( $values['cms_record_i_started'] ) and $values['cms_record_i_started'] and Member::loggedIn()->member_id )
|
||||
{
|
||||
$table->where[] = 'cms_custom_database_' . $database->id . '.member_id=' . \IPS\Member::loggedIn()->member_id;
|
||||
$table->where[] = 'cms_custom_database_' . $database->id . '.member_id=' . Member::loggedIn()->member_id;
|
||||
}
|
||||
|
||||
if ( isset( $values['record_type'] ) )
|
||||
@@ -630,12 +636,12 @@ class _category extends \IPS\cms\Databases\Controller
|
||||
$days = 90;
|
||||
break;
|
||||
case 'since_last_visit':
|
||||
$table->where[] = array( 'record_last_comment>?', \IPS\Member::loggedIn()->last_visit );
|
||||
$table->where[] = array( 'record_last_comment>?', Member::loggedIn()->last_visit );
|
||||
break;
|
||||
}
|
||||
if ( $days !== NULL )
|
||||
{
|
||||
$table->where[] = array( 'record_last_comment>?', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . $days . 'D' ) )->getTimestamp() );
|
||||
$table->where[] = array( 'record_last_comment>?', DateTime::create()->sub( new DateInterval( 'P' . $days . 'D' ) )->getTimestamp() );
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -645,13 +651,13 @@ class _category extends \IPS\cms\Databases\Controller
|
||||
{
|
||||
$rssUrl = $table->baseUrl->setQueryString('rss', 1 );
|
||||
$rssName = $database->_title . ': ' . $category->metaTitle();
|
||||
\IPS\Output::i()->rssFeeds[ $rssName ] = $rssUrl;
|
||||
Output::i()->rssFeeds[ $rssName ] = $rssUrl;
|
||||
|
||||
/* Show RSS feed */
|
||||
if ( isset( \IPS\Request::i()->rss ) )
|
||||
if ( isset( Request::i()->rss ) )
|
||||
{
|
||||
$rssName = \IPS\Member::loggedIn()->language()->get('content_db_' . $database->id ) . ': ' . $category->metaTitle();
|
||||
$document = \IPS\Xml\Rss::newDocument( $table->baseUrl, $rssName, $rssName );
|
||||
$rssName = Member::loggedIn()->language()->get('content_db_' . $database->id ) . ': ' . $category->metaTitle();
|
||||
$document = Rss::newDocument( $table->baseUrl, $rssName, $rssName );
|
||||
$contentField = 'field_' . $database->field_content;
|
||||
|
||||
foreach ( $table->getRows( array() ) as $record )
|
||||
@@ -665,36 +671,43 @@ class _category extends \IPS\cms\Databases\Controller
|
||||
$content = \IPS\cms\Theme::i()->getTemplate( $category->_template_listing, 'cms', 'database' )->rssItemWithImage( $content, $record->record_image );
|
||||
}
|
||||
|
||||
$document->addItem( $record->_title, $record->url(), $content, \IPS\DateTime::ts( ( $record->record_last_comment > $record->record_publish_date ) ? $record->record_publish_date : $record->record_last_comment ), $record->_id );
|
||||
$document->addItem( $record->_title, $record->url(), $content, DateTime::ts( ( $record->record_last_comment > $record->record_publish_date ) ? $record->record_publish_date : $record->record_last_comment ), $record->_id );
|
||||
}
|
||||
}
|
||||
|
||||
/* @note application/rss+xml is not a registered IANA mime-type so we need to stick with text/xml for RSS */
|
||||
\IPS\Output::i()->sendOutput( $document->asXML(), 200, 'text/xml', array(), TRUE );
|
||||
Output::i()->sendOutput( $document->asXML(), 200, 'text/xml' );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->metaTags['title'] = $category->metaTitle();
|
||||
\IPS\Output::i()->metaTags['description'] = $category->metaDescription();
|
||||
\IPS\Output::i()->metaTags['og:title'] = $category->metaTitle();
|
||||
\IPS\Output::i()->metaTags['og:description'] = $category->metaDescription();
|
||||
\IPS\Output::i()->linkTags['canonical'] = (string) $category->url();
|
||||
Output::i()->metaTags['title'] = $category->metaTitle();
|
||||
Output::i()->metaTags['description'] = $category->metaDescription();
|
||||
Output::i()->metaTags['og:title'] = $category->metaTitle();
|
||||
Output::i()->metaTags['og:description'] = $category->metaDescription();
|
||||
Output::i()->linkTags['canonical'] = (string) $category->url();
|
||||
|
||||
/* Set breadcrumb */
|
||||
foreach ( $category->parents() as $parent )
|
||||
if ( $club = $category->_club )
|
||||
{
|
||||
\IPS\Output::i()->breadcrumb[] = array( $parent->url(), $parent->_title );
|
||||
$club->setBreadcrumbs( $category );
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ( $category->parents() as $parent )
|
||||
{
|
||||
Output::i()->breadcrumb[] = array( $parent->url(), $parent->_title );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->breadcrumb[] = array( NULL, $category->_title );
|
||||
Output::i()->breadcrumb[] = array( NULL, $category->_title );
|
||||
}
|
||||
}
|
||||
|
||||
/* Node handler does not support keywords, so we need to do it manually */
|
||||
if ( $category->meta_keywords )
|
||||
{
|
||||
\IPS\Output::i()->metaTags['keywords'] = $category->meta_keywords;
|
||||
Output::i()->metaTags['keywords'] = $category->meta_keywords;
|
||||
}
|
||||
|
||||
/* Show club header, if applicable */
|
||||
@@ -702,71 +715,38 @@ class _category extends \IPS\cms\Databases\Controller
|
||||
|
||||
/* Update location */
|
||||
$permissions = $category->permissions();
|
||||
\IPS\Session::i()->setLocation( $category->url(), explode( ",", $permissions['perm_view'] ), 'loc_cms_viewing_db_cat', array( 'content_db_' . $database->id => TRUE, 'content_cat_name_' . $category->id => TRUE ) );
|
||||
Session::i()->setLocation( $category->url(), explode( ",", $permissions['perm_view'] ), 'loc_cms_viewing_db_cat', array( 'content_db_' . $database->id => TRUE, 'content_cat_name_' . $category->id => TRUE ) );
|
||||
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'records/list.css', 'cms', 'front' ) );
|
||||
Output::i()->cssFiles = array_merge( Output::i()->cssFiles, Theme::i()->css( 'records/list.css', 'cms', 'front' ) );
|
||||
|
||||
$stringTable = ( ( $category->hasChildren() AND $category->show_records ) OR ! $category->hasChildren() ) ? (string) $table : '';
|
||||
|
||||
\IPS\cms\Databases\Dispatcher::i()->output .= \IPS\cms\Theme::i()->getTemplate( $category->_template_listing, 'cms', 'database' )->categoryHeader( $category, $stringTable, static::$activeFilters );
|
||||
Dispatcher::i()->output .= \IPS\cms\Theme::i()->getTemplate( $category->_template_listing, 'cms', 'database' )->categoryHeader( $category, $stringTable, static::$activeFilters );
|
||||
|
||||
\IPS\cms\Databases\Dispatcher::i()->output .= $stringTable;
|
||||
Dispatcher::i()->output .= $stringTable;
|
||||
|
||||
\IPS\cms\Databases\Dispatcher::i()->output .= \IPS\cms\Theme::i()->getTemplate( $category->_template_listing, 'cms', 'database' )->categoryFooter( $category, $stringTable, static::$activeFilters );
|
||||
Dispatcher::i()->output .= \IPS\cms\Theme::i()->getTemplate( $category->_template_listing, 'cms', 'database' )->categoryFooter( $category, $stringTable, static::$activeFilters );
|
||||
|
||||
/* Set default search */
|
||||
if ( ! $database->search )
|
||||
{
|
||||
\IPS\Output::i()->defaultSearchOption = array( 'all', 'search_everything' );
|
||||
Output::i()->defaultSearchOption = array( 'all', 'search_everything' );
|
||||
}
|
||||
else
|
||||
{
|
||||
$type = mb_strtolower( str_replace( '\\', '_', mb_substr( $RecordsClass, 4 ) ) );
|
||||
\IPS\Output::i()->defaultSearchOption = array( $type, "{$type}_pl" );
|
||||
$type = mb_strtolower( str_replace( '\\', '_', mb_substr( $recordsClass, 4 ) ) );
|
||||
Output::i()->defaultSearchOption = array( $type, "{$type}_pl" );
|
||||
}
|
||||
|
||||
$titleSuffix = $database->use_categories ? $category->_title . ' - ' . $category->pageTitle() : $category->pageTitle();
|
||||
|
||||
if( ( $category->hasChildren() AND $category->show_records ) OR ! $category->hasChildren() )
|
||||
{
|
||||
\IPS\Output::i()->title = ( $table->page > 1 ) ? \IPS\Member::loggedIn()->language()->addToStack( 'title_with_page_number', FALSE, array( 'sprintf' => array( $titleSuffix, $table->page ) ) ) : $titleSuffix;
|
||||
Output::i()->title = ( $table->page > 1 ) ? Member::loggedIn()->language()->addToStack( 'title_with_page_number', FALSE, array( 'sprintf' => array( $titleSuffix, $table->page ) ) ) : $titleSuffix;
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->title = $titleSuffix;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show Club Header
|
||||
*
|
||||
* @param \IPS\cms\Categories $category
|
||||
* @return void
|
||||
*/
|
||||
protected function showClubHeader( \IPS\cms\Categories $category )
|
||||
{
|
||||
if ( $club = $category->_club )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['contextual'] = '';
|
||||
|
||||
/* Club info in sidebar */
|
||||
if ( \IPS\Settings::i()->clubs_header == 'sidebar' )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['enabled'] = true;
|
||||
\IPS\Output::i()->sidebar['contextual'] .= \IPS\Theme::i()->getTemplate( 'clubs', 'core', 'front' )->header( $club, $category, 'sidebar' );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\cms\Databases\Dispatcher::i()->output .= \IPS\Theme::i()->getTemplate( 'clubs', 'core', 'front' )->header( $club, $category, 'full' );
|
||||
}
|
||||
|
||||
if( ( \IPS\GeoLocation::enabled() and \IPS\Settings::i()->clubs_locations AND $location = $club->location() ) )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['enabled'] = true;
|
||||
\IPS\Output::i()->sidebar['contextual'] .= \IPS\Theme::i()->getTemplate( 'clubs', 'core', 'front' )->clubLocationBox( $club, $location );
|
||||
}
|
||||
|
||||
$club->setBreadcrumbs( $category );
|
||||
Output::i()->title = $titleSuffix;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -775,23 +755,27 @@ class _category extends \IPS\cms\Databases\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function form()
|
||||
public function form() : void
|
||||
{
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js('front_records.js', 'cms' ) );
|
||||
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, Output::i()->js('front_records.js', 'cms' ) );
|
||||
|
||||
$database = \IPS\cms\Databases::load( \IPS\cms\Databases\Dispatcher::i()->databaseId );
|
||||
$recordClass = '\IPS\cms\Records' . \IPS\cms\Databases\Dispatcher::i()->databaseId;
|
||||
$categoryClass = '\IPS\cms\Categories' . \IPS\cms\Databases\Dispatcher::i()->databaseId;
|
||||
$category = $categoryClass::loadAndCheckPerms( \IPS\cms\Databases\Dispatcher::i()->categoryId );
|
||||
$fieldsClass = '\IPS\cms\Fields' . \IPS\cms\Databases\Dispatcher::i()->databaseId;
|
||||
$title = \IPS\Member::loggedIn()->language()->addToStack( 'content_record_form_new_record', FALSE, array( 'sprintf' => array( $database->recordWord( 1, TRUE ) ) ) );
|
||||
/* @var Categories $categoryClass
|
||||
* @var Records $recordClass
|
||||
* @var Fields $fieldsClass
|
||||
*/
|
||||
$database = Databases::load( Dispatcher::i()->databaseId );
|
||||
$recordClass = '\IPS\cms\Records' . Dispatcher::i()->databaseId;
|
||||
$categoryClass = '\IPS\cms\Categories' . Dispatcher::i()->databaseId;
|
||||
$category = $categoryClass::loadAndCheckPerms( Dispatcher::i()->categoryId );
|
||||
$fieldsClass = '\IPS\cms\Fields' . Dispatcher::i()->databaseId;
|
||||
$title = Member::loggedIn()->language()->addToStack( 'content_record_form_new_record', FALSE, array( 'sprintf' => array( $database->recordWord( 1, TRUE ) ) ) );
|
||||
|
||||
$form = $recordClass::create( $category );
|
||||
$form->class = 'ipsForm_vertical';
|
||||
$form->class = 'ipsForm--vertical ipsForm--database-category';
|
||||
|
||||
$hasModOptions = FALSE;
|
||||
|
||||
$canHide = ( \IPS\Member::loggedIn()->group['g_hide_own_posts'] == '1' or \in_array( 'IPS\cms\Records' . \IPS\cms\Databases\Dispatcher::i()->databaseId, explode( ',', \IPS\Member::loggedIn()->group['g_hide_own_posts'] ) ) );
|
||||
$canHide = ( Member::loggedIn()->group['g_hide_own_posts'] == '1' or in_array( 'IPS\cms\Records' . Dispatcher::i()->databaseId, explode( ',', Member::loggedIn()->group['g_hide_own_posts'] ) ) );
|
||||
if ( $recordClass::modPermission( 'lock', NULL, $category ) or
|
||||
$recordClass::modPermission( 'pin', NULL, $category ) or
|
||||
$canHide or
|
||||
@@ -799,34 +783,33 @@ class _category extends \IPS\cms\Databases\Controller
|
||||
$fieldsClass::fixedFieldFormShow( 'record_allow_comments' ) or
|
||||
$fieldsClass::fixedFieldFormShow( 'record_expiry_date' ) or
|
||||
$fieldsClass::fixedFieldFormShow( 'record_comment_cutoff' ) or
|
||||
\IPS\Member::loggedIn()->modPermission('can_content_edit_meta_tags') )
|
||||
Member::loggedIn()->modPermission('can_content_edit_meta_tags') )
|
||||
{
|
||||
$hasModOptions = TRUE;
|
||||
}
|
||||
|
||||
$this->showClubHeader( $category );
|
||||
Output::i()->allowDefaultWidgets = FALSE;
|
||||
Output::i()->sidebar['enabled'] = FALSE;
|
||||
Output::i()->output = $form->customTemplate( array( \IPS\cms\Theme::i()->getTemplate( $database->template_form, 'cms', 'database' ), 'recordForm' ), NULL, $category, $database, Page::$currentPage, $title, $hasModOptions );
|
||||
Dispatcher::i()->output .= Output::i()->output;
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack( $title );
|
||||
Output::i()->cssFiles = array_merge( Output::i()->cssFiles, Theme::i()->css( 'records/form.css', 'cms', 'front' ) );
|
||||
|
||||
try
|
||||
{
|
||||
if ( $database->use_categories )
|
||||
{
|
||||
foreach( $category->parents() AS $parent )
|
||||
{
|
||||
\IPS\Output::i()->breadcrumb[] = array( $parent->url(), $parent->_title );
|
||||
Output::i()->breadcrumb[] = array( $parent->url(), $parent->_title );
|
||||
}
|
||||
\IPS\Output::i()->breadcrumb[] = array( $category->url(), $category->_title );
|
||||
Output::i()->breadcrumb[] = array( $category->url(), $category->_title );
|
||||
}
|
||||
}
|
||||
catch( \Exception $e ) {}
|
||||
|
||||
\IPS\Output::i()->breadcrumb[] = array( NULL, $title );
|
||||
|
||||
$this->showClubHeader( $category );
|
||||
\IPS\Output::i()->allowDefaultWidgets = FALSE;
|
||||
\IPS\Output::i()->sidebar['enabled'] = FALSE;
|
||||
\IPS\cms\Pages\Page::$currentPage->getWidgets();
|
||||
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\cms\Theme::i()->getTemplate( $database->template_form, 'cms', 'database' ), 'recordForm' ), NULL, $category, $database, \IPS\cms\Pages\Page::$currentPage, $title, $hasModOptions );
|
||||
\IPS\cms\Databases\Dispatcher::i()->output .= \IPS\Output::i()->output;
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( $title );
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'records/form.css', 'cms', 'front' ) );
|
||||
catch( Exception $e ) {}
|
||||
|
||||
Output::i()->breadcrumb[] = array( NULL, $title );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -834,21 +817,52 @@ class _category extends \IPS\cms\Databases\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function markRead()
|
||||
protected function markRead() : void
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
try
|
||||
{
|
||||
$meowBreed = '\IPS\cms\Categories' . \IPS\cms\Databases\Dispatcher::i()->databaseId;
|
||||
$meow = $meowBreed::load( \IPS\cms\Databases\Dispatcher::i()->categoryId );
|
||||
\IPS\cms\Records::markContainerRead( $meow );
|
||||
\IPS\Output::i()->redirect( $meow->url() );
|
||||
/* @var Categories $meowBreed */
|
||||
$meowBreed = '\IPS\cms\Categories' . Dispatcher::i()->databaseId;
|
||||
$meow = $meowBreed::load( Dispatcher::i()->categoryId );
|
||||
Records::markContainerRead( $meow );
|
||||
Output::i()->redirect( $meow->url() );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'module_no_permission', '2T254/3', 403, '' );
|
||||
Output::i()->error( 'module_no_permission', '2T254/3', 403, '' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show Club header
|
||||
*
|
||||
* @param Categories $category
|
||||
* @return void
|
||||
*/
|
||||
protected function showClubHeader( Categories $category ) : void
|
||||
{
|
||||
if ( $club = $category->_club )
|
||||
{
|
||||
Output::i()->sidebar['contextual'] = '';
|
||||
|
||||
/* Club info in sidebar */
|
||||
if ( Settings::i()->clubs_header == 'sidebar' )
|
||||
{
|
||||
Output::i()->sidebar['enabled'] = true;
|
||||
Output::i()->sidebar['contextual'] .= Theme::i()->getTemplate( 'clubs', 'core', 'front' )->header( $club, $category, 'sidebar' );
|
||||
}
|
||||
else
|
||||
{
|
||||
Dispatcher::i()->output .= Theme::i()->getTemplate( 'clubs', 'core', 'front' )->header( $club, $category, 'full' );
|
||||
}
|
||||
|
||||
if( ( GeoLocation::enabled() and Settings::i()->clubs_locations AND $location = $club->location() ) )
|
||||
{
|
||||
Output::i()->sidebar['enabled'] = true;
|
||||
Output::i()->sidebar['contextual'] .= Theme::i()->getTemplate( 'clubs', 'core', 'front' )->clubLocationBox( $club, $location );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,16 +12,40 @@
|
||||
namespace IPS\cms\modules\front\database;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\cms\Categories;
|
||||
use IPS\cms\Databases;
|
||||
use IPS\cms\Databases\Controller;
|
||||
use IPS\cms\Databases\Dispatcher;
|
||||
use IPS\cms\Pages\Page;
|
||||
use IPS\cms\Records;
|
||||
use IPS\Content\Filter;
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\Node;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
use IPS\Theme;
|
||||
use IPS\Xml\Rss;
|
||||
use OutOfRangeException;
|
||||
use function count;
|
||||
use function defined;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* List
|
||||
*/
|
||||
class _index extends \IPS\cms\Databases\Controller
|
||||
class index extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
@@ -29,23 +53,25 @@ class _index extends \IPS\cms\Databases\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function manage()
|
||||
public function manage() : void
|
||||
{
|
||||
/* If the Databases module is set as default we end up here, but not routed through the database dispatcher which means the
|
||||
database ID isn't set. In that case, just re-route back through the pages controller which handles everything. */
|
||||
if( \IPS\cms\Databases\Dispatcher::i()->databaseId === NULL )
|
||||
if( Dispatcher::i()->databaseId === NULL )
|
||||
{
|
||||
$pages = new \IPS\cms\modules\front\pages\page;
|
||||
return $pages->manage();
|
||||
$pages->manage();
|
||||
return;
|
||||
}
|
||||
|
||||
$database = \IPS\cms\Databases::load( \IPS\cms\Databases\Dispatcher::i()->databaseId );
|
||||
$database = Databases::load( Dispatcher::i()->databaseId );
|
||||
|
||||
/* Not using categories? */
|
||||
if ( ! $database->use_categories AND $database->cat_index_type === 0 )
|
||||
if ( ! $database->use_categories AND $database->display_settings['index']['type'] == 'categories' )
|
||||
{
|
||||
$controller = new \IPS\cms\modules\front\database\category( $this->url );
|
||||
return $controller->view();
|
||||
$controller = new category( $this->url );
|
||||
$controller->view();
|
||||
return;
|
||||
}
|
||||
|
||||
$this->view();
|
||||
@@ -56,25 +82,26 @@ class _index extends \IPS\cms\Databases\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function view()
|
||||
protected function view() : void
|
||||
{
|
||||
$database = \IPS\cms\Databases::load( \IPS\cms\Databases\Dispatcher::i()->databaseId );
|
||||
$recordClass = 'IPS\cms\Records' . \IPS\cms\Databases\Dispatcher::i()->databaseId;
|
||||
$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 );
|
||||
$database = Databases::load( Dispatcher::i()->databaseId );
|
||||
$recordClass = 'IPS\cms\Records' . Dispatcher::i()->databaseId;
|
||||
$url = Url::internal( "app=cms&module=pages&controller=page&path=" . Page::$currentPage->full_path, 'front', 'content_page_path', Page::$currentPage->full_path );
|
||||
|
||||
/* RSS */
|
||||
if ( $database->rss )
|
||||
{
|
||||
/* Show the link */
|
||||
\IPS\Output::i()->rssFeeds[ $database->_title ] = $url->setQueryString( 'rss', 1 );
|
||||
Output::i()->rssFeeds[ $database->_title ] = $url->setQueryString( 'rss', 1 );
|
||||
|
||||
/* Or actually show RSS feed */
|
||||
if ( isset( \IPS\Request::i()->rss ) )
|
||||
if ( isset( Request::i()->rss ) )
|
||||
{
|
||||
$document = \IPS\Xml\Rss::newDocument( $url, \IPS\Member::loggedIn()->language()->get('content_db_' . $database->id ), \IPS\Member::loggedIn()->language()->get('content_db_' . $database->id . '_desc' ) );
|
||||
$document = Rss::newDocument( $url, Member::loggedIn()->language()->get('content_db_' . $database->id ), Member::loggedIn()->language()->get('content_db_' . $database->id . '_desc' ) );
|
||||
$contentField = 'field_' . $database->field_content;
|
||||
|
||||
foreach ( $recordClass::getItemsWithPermission( array(), $database->field_sort . ' ' . $database->field_direction, $database->rss, 'read' ) as $record )
|
||||
|
||||
/* @var Records $recordClass */
|
||||
foreach ( $recordClass::getItemsWithPermission( array(), $database->field_sort . ' ' . $database->field_direction, $database->rss ) as $record )
|
||||
{
|
||||
$content = $record->$contentField;
|
||||
|
||||
@@ -83,67 +110,96 @@ class _index extends \IPS\cms\Databases\Controller
|
||||
$content = \IPS\cms\Theme::i()->getTemplate( 'listing', 'cms', 'database' )->rssItemWithImage( $content, $record->record_image );
|
||||
}
|
||||
|
||||
$document->addItem( $record->_title, $record->url(), $content, \IPS\DateTime::ts( $record->_publishDate ), $record->_id );
|
||||
$document->addItem( $record->_title, $record->url(), $content, DateTime::ts( $record->_publishDate ), $record->_id );
|
||||
}
|
||||
|
||||
/* @note application/rss+xml is not a registered IANA mime-type so we need to stick with text/xml for RSS */
|
||||
\IPS\Output::i()->sendOutput( $document->asXML(), 200, 'text/xml', array(), TRUE );
|
||||
Output::i()->sendOutput( $document->asXML(), 200, 'text/xml' );
|
||||
}
|
||||
}
|
||||
|
||||
$page = isset( \IPS\Request::i()->page ) ? \intval( \IPS\Request::i()->page ) : 1;
|
||||
$page = isset( Request::i()->page ) ? intval( Request::i()->page ) : 1;
|
||||
|
||||
if( $page < 1 )
|
||||
{
|
||||
$page = 1;
|
||||
}
|
||||
|
||||
if ( $database->cat_index_type === 1 and ! isset( \IPS\Request::i()->show ) )
|
||||
if ( $database->display_settings['index']['type'] != 'categories' and ! isset( Request::i()->show ) )
|
||||
{
|
||||
/* Featured */
|
||||
$limit = 0;
|
||||
$count = 0;
|
||||
$perPage = ( $database->field_perpage ?? 25 );
|
||||
|
||||
if ( isset( \IPS\Request::i()->page ) )
|
||||
if ( isset( Request::i()->page ) )
|
||||
{
|
||||
$limit = $database->featured_settings['perpage'] * ( $page - 1 );
|
||||
$limit = $perPage * ( $page - 1 );
|
||||
}
|
||||
|
||||
$where = ( $database->featured_settings['featured'] ) ? array( array( 'record_featured=?', 1 ) ) : NULL;
|
||||
|
||||
if ( isset( $database->featured_settings['categories'] ) and \is_array( $database->featured_settings['categories'] ) and \count( $database->featured_settings['categories'] ) )
|
||||
{
|
||||
$categoryField = "`cms_custom_database_{$database->_id}`.`category_id`";
|
||||
$where[] = array( \IPS\Db::i()->in( $categoryField, array_values( $database->featured_settings['categories'] ) ) );
|
||||
}
|
||||
|
||||
$articles = $recordClass::getItemsWithPermission( $where, 'record_pinned DESC, ' . $database->featured_settings['sort'] . ' ' . $database->featured_settings['direction'], array( $limit, $database->featured_settings['perpage'] ), 'read', \IPS\Content\Hideable::FILTER_AUTOMATIC, 0, NULL, TRUE, FALSE, FALSE, FALSE );
|
||||
$where = [];
|
||||
|
||||
if ( $database->featured_settings['pagination'] )
|
||||
/** @var Categories $categoryClass */
|
||||
$categoryClass = 'IPS\cms\Categories' . $database->id;
|
||||
$category = $categoryClass::load( $database->_default_category );
|
||||
$cookie = $category->getFilterCookie();
|
||||
if( $cookie !== null )
|
||||
{
|
||||
$count = $recordClass::getItemsWithPermission( $where, 'record_pinned DESC, ' . $database->featured_settings['sort'] . ' ' . $database->featured_settings['direction'], $database->featured_settings['perpage'], 'read', \IPS\Content\Hideable::FILTER_AUTOMATIC, 0, NULL, FALSE, FALSE, FALSE, TRUE );
|
||||
$where = $category->buildWhereFromCookie( $cookie );
|
||||
}
|
||||
elseif( isset( Request::i()->advanced_search_submitted ) and Request::i()->advanced_search_submitted )
|
||||
{
|
||||
$cookie = [];
|
||||
foreach( Request::i() as $k => $v )
|
||||
{
|
||||
if( $k == 'cms_record_i_started' )
|
||||
{
|
||||
$cookie[ $k ] = $v;
|
||||
}
|
||||
elseif( str_starts_with( $k, 'content_field_' ) )
|
||||
{
|
||||
$cookie[ mb_substr( $k, 14 ) ] = $v;
|
||||
}
|
||||
}
|
||||
if( count( $cookie ) )
|
||||
{
|
||||
$where = $category->buildWhereFromCookie( $cookie );
|
||||
}
|
||||
}
|
||||
|
||||
if( $database->display_settings['index']['type'] == 'featured' )
|
||||
{
|
||||
$where[] = [ 'record_featured=?', 1 ];
|
||||
}
|
||||
|
||||
$sort = ( $database->field_sort ? $recordClass::$databaseTable . '.' . $recordClass::$databasePrefix . $database->field_sort : 'record_last_comment' );
|
||||
$sortDirection = $database->field_direction ?? 'desc';
|
||||
|
||||
$articles = $recordClass::getItemsWithPermission( $where, 'record_pinned DESC, ' . $sort . ' ' . $sortDirection, array( $limit, $perPage ), 'read', Filter::FILTER_AUTOMATIC, 0, NULL, TRUE );
|
||||
|
||||
$count = $recordClass::getItemsWithPermission( $where, 'record_pinned DESC, ' . $sort . ' ' . $sortDirection, $perPage, 'read', Filter::FILTER_AUTOMATIC, 0, NULL, FALSE, FALSE, FALSE, TRUE );
|
||||
|
||||
/* Pagination */
|
||||
$pagination = array(
|
||||
'page' => $page,
|
||||
'pages' => ( $count > 0 ) ? ceil( $count / $database->featured_settings['perpage'] ) : 1
|
||||
'pages' => ( $count > 0 ) ? ceil( $count / $perPage ) : 1
|
||||
);
|
||||
|
||||
/* Make sure we are viewing a real page */
|
||||
if ( $page > $pagination['pages'] )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Request::i()->url()->setPage( 'page', 1 ), NULL, 303 );
|
||||
Output::i()->redirect( Request::i()->url()->setPage( 'page', 1 ), NULL, 303 );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'database_index/featured.css', 'cms', 'front' ) );
|
||||
\IPS\Output::i()->title = ( $page > 1 ) ? \IPS\Member::loggedIn()->language()->addToStack( 'title_with_page_number', FALSE, array( 'sprintf' => array( $database->pageTitle(), $page ) ) ) : $database->pageTitle();
|
||||
Output::i()->cssFiles = array_merge( Output::i()->cssFiles, Theme::i()->css( 'database_index/featured.css', 'cms', 'front' ) );
|
||||
Output::i()->title = ( $page > 1 ) ? Member::loggedIn()->language()->addToStack( 'title_with_page_number', FALSE, array( 'sprintf' => array( $database->pageTitle(), $page ) ) ) : $database->pageTitle();
|
||||
|
||||
\IPS\cms\Databases\Dispatcher::i()->output .= \IPS\Output::i()->output = \IPS\cms\Theme::i()->getTemplate( $database->template_featured, 'cms', 'database' )->index( $database, $articles, $url, $pagination );
|
||||
Dispatcher::i()->output .= Output::i()->output = \IPS\cms\Theme::i()->getTemplate( $database->template_featured, 'cms', 'database' )->index( $database, $articles, $url, $pagination );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Category view */
|
||||
/* @var Categories $class */
|
||||
$class = '\IPS\cms\Categories' . $database->id;
|
||||
|
||||
/* Load into memory */
|
||||
@@ -159,9 +215,8 @@ class _index extends \IPS\cms\Databases\Controller
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'records/index.css', 'cms', 'front' ) );
|
||||
\IPS\Output::i()->title = $database->pageTitle();
|
||||
\IPS\cms\Databases\Dispatcher::i()->output .= \IPS\Output::i()->output = \IPS\cms\Theme::i()->getTemplate( $database->template_categories, 'cms', 'database' )->index( $database, $categories, $url );
|
||||
Output::i()->title = $database->pageTitle();
|
||||
Dispatcher::i()->output .= Output::i()->output = \IPS\cms\Theme::i()->getTemplate( $database->template_categories, 'cms', 'database' )->index( $database, $categories, $url );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,32 +225,31 @@ class _index extends \IPS\cms\Databases\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function form()
|
||||
protected function form() : void
|
||||
{
|
||||
/* If the page is the default page and Pages is the default app, the node selector cannot find the page as it bypasses the Database dispatcher */
|
||||
if ( \IPS\cms\Pages\Page::$currentPage === NULL and \IPS\cms\Databases\Dispatcher::i()->databaseId === NULL and isset( \IPS\Request::i()->page_id ) )
|
||||
if ( Page::$currentPage === NULL and Dispatcher::i()->databaseId === NULL and isset( Request::i()->page_id ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\cms\Pages\Page::$currentPage = \IPS\cms\Pages\Page::load( \IPS\Request::i()->page_id );
|
||||
$database = \IPS\cms\Pages\Page::$currentPage->getDatabase();
|
||||
|
||||
Page::$currentPage = Page::load( Request::i()->page_id );
|
||||
$database = Page::$currentPage->getDatabase();
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
catch( OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'content_err_page_404', '2T389/1', 404, '' );
|
||||
Output::i()->error( 'content_err_page_404', '2T389/1', 404, '' );
|
||||
}
|
||||
}
|
||||
else if ( \IPS\cms\Pages\Page::$currentPage === NULL and \IPS\cms\Databases\Dispatcher::i()->databaseId === NULL and isset( \IPS\Request::i()->d ) )
|
||||
else if ( Page::$currentPage === NULL and Dispatcher::i()->databaseId === NULL and isset( Request::i()->d ) )
|
||||
{
|
||||
\IPS\cms\Pages\Page::$currentPage = \IPS\cms\Pages\Page::loadByDatabaseId( \IPS\Request::i()->d );
|
||||
Page::$currentPage = Page::loadByDatabaseId( Request::i()->d );
|
||||
}
|
||||
|
||||
$form = new \IPS\Helpers\Form( 'select_category', 'continue' );
|
||||
$form->class = 'ipsForm_vertical ipsForm_noLabels';
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'category', NULL, TRUE, array(
|
||||
'url' => \IPS\cms\Pages\Page::$currentPage->url()->setQueryString( array( 'do' => 'form', 'page_id' => \IPS\cms\Pages\Page::$currentPage->id ) ),
|
||||
'class' => 'IPS\cms\Categories' . \IPS\cms\Pages\Page::$currentPage->getDatabase()->_id,
|
||||
$form = new Form( 'select_category', 'continue' );
|
||||
$form->class = 'ipsForm--vertical ipsForm--select-database-category ipsForm--noLabels';
|
||||
$form->add( new Node( 'category', NULL, TRUE, array(
|
||||
'url' => Page::$currentPage->url()->setQueryString( array( 'do' => 'form', 'page_id' => Page::$currentPage->id ) ),
|
||||
'class' => 'IPS\cms\Categories' . Page::$currentPage->getDatabase()->_id,
|
||||
'permissionCheck' => function( $node )
|
||||
{
|
||||
if ( $node->can( 'view' ) )
|
||||
@@ -214,11 +268,11 @@ class _index extends \IPS\cms\Databases\Controller
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
\IPS\Output::i()->redirect( $values['category']->url()->setQueryString( 'do', 'form' ) );
|
||||
Output::i()->redirect( $values['category']->url()->setQueryString( 'do', 'form' ) );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'cms_select_category' );
|
||||
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack( 'cms_select_category' ) );
|
||||
\IPS\cms\Databases\Dispatcher::i()->output = \IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'records' )->categorySelector( $form );
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack( 'cms_select_category' );
|
||||
Output::i()->breadcrumb[] = array( NULL, Member::loggedIn()->language()->addToStack( 'cms_select_category' ) );
|
||||
Dispatcher::i()->output = Output::i()->output = Theme::i()->getTemplate( 'records' )->categorySelector( $form );
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @brief topic
|
||||
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
|
||||
@@ -12,36 +13,72 @@
|
||||
namespace IPS\cms\modules\front\database;
|
||||
|
||||
/* 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\Fields;
|
||||
use IPS\cms\Pages\Page;
|
||||
use IPS\cms\Records;
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\File;
|
||||
use IPS\forums\Topic as TopicClass;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\Custom;
|
||||
use IPS\Helpers\Form\Editor;
|
||||
use IPS\Helpers\Form\Node;
|
||||
use IPS\Helpers\Form\YesNo;
|
||||
use IPS\Helpers\MultipleRedirect;
|
||||
use IPS\Helpers\Wizard;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\Output;
|
||||
use IPS\Patterns\ActiveRecordIterator;
|
||||
use IPS\Request;
|
||||
use IPS\Session;
|
||||
use IPS\Theme;
|
||||
use LogicException;
|
||||
use OutOfRangeException;
|
||||
use function defined;
|
||||
use function in_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;
|
||||
}
|
||||
|
||||
/**
|
||||
* topic
|
||||
*/
|
||||
class _topic extends \IPS\Dispatcher\Controller
|
||||
class topic extends Controller
|
||||
{
|
||||
/**
|
||||
* @var TopicClass|null
|
||||
*/
|
||||
protected ?TopicClass $topic = null;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function execute()
|
||||
public function execute() : void
|
||||
{
|
||||
if ( !\IPS\Member::loggedIn()->modPermission( 'can_copy_topic_database' ) )
|
||||
if ( !Member::loggedIn()->modPermission( 'can_copy_topic_database' ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2T353/1', 403, '' );
|
||||
Output::i()->error( 'node_error', '2T353/1', 403, '' );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$this->topic = \IPS\forums\Topic::load( \IPS\Request::i()->id );
|
||||
$this->topic = TopicClass::load( Request::i()->id );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
catch( OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2T353/3', 404, '' );
|
||||
Output::i()->error( 'node_error', '2T353/3', 404, '' );
|
||||
}
|
||||
|
||||
parent::execute();
|
||||
@@ -52,37 +89,37 @@ class _topic extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function manage()
|
||||
protected function manage() : void
|
||||
{
|
||||
$wizard = new \IPS\Helpers\Wizard( array(
|
||||
$wizard = new Wizard( array(
|
||||
'database' => array( $this, '_database' ),
|
||||
'category' => array( $this, '_category' ),
|
||||
), \IPS\Http\Url::internal( "app=cms&module=database&controller=topic&id=" . \IPS\Request::i()->id, 'front', 'topic_copy', $this->topic->title_seo ), FALSE );
|
||||
), Url::internal( "app=cms&module=database&controller=topic&id=" . Request::i()->id, 'front', 'topic_copy', $this->topic->title_seo ), FALSE );
|
||||
|
||||
/* Set Breadcrumb */
|
||||
foreach ( $this->topic->container()->parents() as $parent )
|
||||
{
|
||||
\IPS\Output::i()->breadcrumb[] = array( $parent->url(), $parent->_title );
|
||||
Output::i()->breadcrumb[] = array( $parent->url(), $parent->_title );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->breadcrumb[] = array( $this->topic->container()->url(), $this->topic->container()->_title );
|
||||
Output::i()->breadcrumb[] = array( $this->topic->container()->url(), $this->topic->container()->_title );
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'copy_topic_to_database' );
|
||||
\IPS\Output::i()->output = (string) $wizard;
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack( 'copy_topic_to_database' );
|
||||
Output::i()->output = (string) $wizard;
|
||||
}
|
||||
|
||||
/**
|
||||
* Database
|
||||
*
|
||||
* @param mixed $data Data
|
||||
* @return void
|
||||
* @return array|string
|
||||
*/
|
||||
public function _database( $data )
|
||||
public function _database( mixed $data ) : array|string
|
||||
{
|
||||
$form = new \IPS\Helpers\Form( 'database', 'copy_select_database', \IPS\Http\Url::internal( "app=cms&module=database&controller=topic&id=" . \IPS\Request::i()->id, 'front', 'topic_copy', $this->topic->title_seo ) );
|
||||
$form->class = 'ipsForm_vertical';
|
||||
$form->hiddenValues['topic_id'] = \IPS\Request::i()->id;
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'database', NULL, TRUE, array( 'class' => '\IPS\cms\Databases', 'permissionCheck' => function( $row )
|
||||
$form = new Form( 'database', 'copy_select_database', Url::internal( "app=cms&module=database&controller=topic&id=" . Request::i()->id, 'front', 'topic_copy', $this->topic->title_seo ) );
|
||||
$form->class = 'ipsForm--vertical ipsForm--copy-database-topic';
|
||||
$form->hiddenValues['topic_id'] = Request::i()->id;
|
||||
$form->add( new Node( 'database', NULL, TRUE, array( 'class' => '\IPS\cms\Databases', 'permissionCheck' => function( $row )
|
||||
{
|
||||
/* If this database does not have a title or content field, we cannot copy. */
|
||||
if ( !$row->field_title OR !$row->field_content )
|
||||
@@ -106,39 +143,39 @@ class _topic extends \IPS\Dispatcher\Controller
|
||||
);
|
||||
}
|
||||
|
||||
return $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );
|
||||
return $form->customTemplate( array( Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Category
|
||||
*
|
||||
* @param mixed $data Data
|
||||
* @return void
|
||||
* @return string
|
||||
*/
|
||||
public function _category( $data )
|
||||
public function _category( mixed $data ) : string
|
||||
{
|
||||
/* Do we need to even bother? */
|
||||
$database = \IPS\cms\Databases::load( $data['database_id'] );
|
||||
$database = Databases::load( $data['database_id'] );
|
||||
|
||||
if ( !$database->use_categories )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=cms&module=database&controller=topic&do=form&id={$data['topic_id']}", 'front', 'topic_copy', $this->topic->title_seo )->setQueryString( array( 'database_id' => $data['database_id'], 'category_id' => $database->default_category ) ) );
|
||||
Output::i()->redirect( Url::internal( "app=cms&module=database&controller=topic&do=form&id={$data['topic_id']}", 'front', 'topic_copy', $this->topic->title_seo )->setQueryString( array( 'database_id' => $data['database_id'], 'category_id' => $database->default_category ) ) );
|
||||
}
|
||||
|
||||
$catClass = 'IPS\cms\Categories' . $data['database_id'];
|
||||
|
||||
$form = new \IPS\Helpers\Form( 'category', 'copy_select_category', \IPS\Http\Url::internal( "app=cms&module=database&controller=topic&id=" . \IPS\Request::i()->id, 'front', 'topic_copy', $this->topic->title_seo ) );
|
||||
$form->class = 'ipsForm_vertical';
|
||||
$form = new Form( 'category', 'copy_select_category', Url::internal( "app=cms&module=database&controller=topic&id=" . Request::i()->id, 'front', 'topic_copy', $this->topic->title_seo ) );
|
||||
$form->class = 'ipsForm--vertical ipsForm--copy-database-topic-category';
|
||||
$form->hiddenValues['topic_id'] = $data['topic_id'];
|
||||
$form->hiddenValues['database_id'] = $data['database_id'];
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'select_category', NULL, TRUE, array( 'class' => $catClass, 'permissionCheck' => 'add' ) ) );
|
||||
$form->add( new Node( 'select_category', NULL, TRUE, array( 'class' => $catClass, 'permissionCheck' => 'add' ) ) );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=cms&module=database&controller=topic&do=form&id={$values['topic_id']}", 'front', 'topic_copy', $this->topic->title_seo )->setQueryString( array( 'database_id' => $values['database_id'], 'category_id' => $values['select_category']->_id ) ) );
|
||||
Output::i()->redirect( Url::internal( "app=cms&module=database&controller=topic&do=form&id={$values['topic_id']}", 'front', 'topic_copy', $this->topic->title_seo )->setQueryString( array( 'database_id' => $values['database_id'], 'category_id' => $values['select_category']->_id ) ) );
|
||||
}
|
||||
|
||||
return $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );
|
||||
return $form->customTemplate( array( Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -146,33 +183,35 @@ class _topic extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function form()
|
||||
protected function form() : void
|
||||
{
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js('front_records.js', 'cms' ) );
|
||||
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, Output::i()->js('front_records.js', 'cms' ) );
|
||||
|
||||
try
|
||||
{
|
||||
$database = \IPS\cms\Databases::load( \IPS\Request::i()->database_id );
|
||||
$database = Databases::load( Request::i()->database_id );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
catch( OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2T353/2', 404, '' );
|
||||
Output::i()->error( 'node_error', '2T353/2', 404, '' );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$page = \IPS\cms\Pages\Page::load( $database->page_id );
|
||||
$page = Page::load( $database->page_id );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
catch( OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'node_error', '2T353/4', 404, '' );
|
||||
Output::i()->error( 'node_error', '2T353/4', 404, '' );
|
||||
}
|
||||
|
||||
|
||||
/* @var Categories $catClass
|
||||
* @var Records $recordClass
|
||||
* @var Fields $fieldClass */
|
||||
$recordClass = 'IPS\cms\Records' . $database->_id;
|
||||
$commentClass = 'IPS\cms\Comments' . $database->_id;
|
||||
$fieldClass = 'IPS\cms\Fields' . $database->_id;
|
||||
$catClass = 'IPS\cms\Categories' . $database->_id;
|
||||
$category = $catClass::load( \IPS\Request::i()->category_id );
|
||||
$category = $catClass::load( Request::i()->category_id );
|
||||
|
||||
$titleField = "field_{$database->field_title}";
|
||||
$contentField = "field_{$database->field_content}";
|
||||
@@ -180,27 +219,27 @@ class _topic extends \IPS\Dispatcher\Controller
|
||||
$fakeRecord = new $recordClass;
|
||||
$fakeRecord->$titleField = $this->topic->mapped('title');
|
||||
$fakeRecord->$contentField = $this->topic->content();
|
||||
$fakeRecord->category_id = \IPS\Request::i()->category_id;
|
||||
$fakeRecord->category_id = Request::i()->category_id;
|
||||
|
||||
if( $fakeRecord->_forum_record AND $fakeRecord->_forum_comments )
|
||||
{
|
||||
\IPS\Member::loggedIn()->language()->words['copy_comments_desc'] = sprintf( \IPS\Member::loggedIn()->language()->get( 'copy_comments_assoc_desc' ), $recordClass::_definiteArticle(), $recordClass::_definiteArticle() );
|
||||
Member::loggedIn()->language()->words['copy_comments_desc'] = sprintf( Member::loggedIn()->language()->get( 'copy_comments_assoc_desc' ), $recordClass::_definiteArticle(), $recordClass::_definiteArticle() );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Member::loggedIn()->language()->words['copy_comments_desc'] = sprintf( \IPS\Member::loggedIn()->language()->get( 'copy_comments_desc' ), $recordClass::_definiteArticle() );
|
||||
Member::loggedIn()->language()->words['copy_comments_desc'] = sprintf( Member::loggedIn()->language()->get( 'copy_comments_desc' ), $recordClass::_definiteArticle() );
|
||||
}
|
||||
|
||||
\IPS\Member::loggedIn()->language()->words['copy_author_desc'] = sprintf( \IPS\Member::loggedIn()->language()->get( 'copy_author_desc' ), $recordClass::_definiteArticle() );
|
||||
Member::loggedIn()->language()->words['copy_author_desc'] = sprintf( Member::loggedIn()->language()->get( 'copy_author_desc' ), $recordClass::_definiteArticle() );
|
||||
|
||||
$form = new \IPS\Helpers\Form;
|
||||
$form->class = 'ipsForm_vertical';
|
||||
$form = new Form;
|
||||
$form->class = 'ipsForm--vertical ipsForm--copy-database-topic-categories';
|
||||
$form->hiddenValues['record_category_id'] = $category->_id;
|
||||
|
||||
foreach( $recordClass::formElements( $fakeRecord, $category ) AS $key => $element )
|
||||
{
|
||||
/* Skip these */
|
||||
if ( \in_array( $key, array( 'record_edit_reason', 'record_edit_show' ) ) )
|
||||
if ( in_array( $key, array( 'record_edit_reason', 'record_edit_show' ) ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -210,17 +249,17 @@ class _topic extends \IPS\Dispatcher\Controller
|
||||
|
||||
if ( $database->options['comments'] )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'copy_comments', FALSE, FALSE, array( 'togglesOn' => array( 'comments_show_message' ) ) ) );
|
||||
$form->add( new YesNo( 'copy_comments', FALSE, FALSE, array( 'togglesOn' => array( 'comments_show_message' ) ) ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'comments_show_message', TRUE, FALSE, array( 'togglesOn' => array( 'comments_meta_message', 'comments_meta_color' ) ), NULL, NULL, NULL, 'comments_show_message' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Editor( 'comments_meta_message', \IPS\Member::loggedIn()->language()->addToStack('default_copyposts_message'), FALSE, array( 'app' => 'core', 'key' => 'Meta', 'autoSaveKey' => "meta-message-new", 'attachIds' => NULL ), NULL, NULL, NULL, 'comments_meta_message' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Custom( 'comments_meta_color', 'none', FALSE, array( 'getHtml' => function( $element )
|
||||
$form->add( new YesNo( 'comments_show_message', TRUE, FALSE, array( 'togglesOn' => array( 'comments_meta_message', 'comments_meta_color' ) ), NULL, NULL, NULL, 'comments_show_message' ) );
|
||||
$form->add( new Editor( 'comments_meta_message', Member::loggedIn()->language()->addToStack('default_copyposts_message'), FALSE, array( 'app' => 'core', 'key' => 'Meta', 'autoSaveKey' => "meta-message-new", 'attachIds' => NULL ), NULL, NULL, NULL, 'comments_meta_message' ) );
|
||||
$form->add( new Custom( 'comments_meta_color', 'none', FALSE, array( 'getHtml' => function( $element )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'forms', 'core', 'front' )->colorSelection( $element->name, $element->value );
|
||||
return Theme::i()->getTemplate( 'forms', 'core', 'front' )->colorSelection( $element->name, $element->value );
|
||||
} ), NULL, NULL, NULL, 'comments_meta_color' ) );
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'copy_author', TRUE ) );
|
||||
$form->add( new YesNo( 'copy_author', TRUE ) );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
@@ -249,7 +288,7 @@ class _topic extends \IPS\Dispatcher\Controller
|
||||
unset( $values['copy_author'] );
|
||||
|
||||
/* If we are copying comments and we use the forums for comments, skip creating a topic as we will just reassocciate */
|
||||
if( $comments AND $fakeRecord->_forum_record AND $fakeRecord->_forum_comments )
|
||||
if( $fakeRecord->_forum_record )
|
||||
{
|
||||
$recordClass::$skipTopicCreation = true;
|
||||
}
|
||||
@@ -266,46 +305,49 @@ class _topic extends \IPS\Dispatcher\Controller
|
||||
if( $metaMessage['show'] )
|
||||
{
|
||||
$id = $record->addMessage( $metaMessage['message'], $metaMessage['color'] );
|
||||
\IPS\File::claimAttachments( "meta-message-new", $id, NULL, 'core_ContentMessages' );
|
||||
File::claimAttachments( "meta-message-new", $id, NULL, 'core_ContentMessages' );
|
||||
}
|
||||
}
|
||||
|
||||
/* If the record syncs with the forums and we are copying topics, just associate with the existing topic */
|
||||
if( $comments AND $record->_forum_record AND $record->_forum_comments )
|
||||
if( $record->_forum_record )
|
||||
{
|
||||
$record->record_topicid = $this->topic->tid;
|
||||
$record->save();
|
||||
|
||||
/* Reload using the proper class so first and last comment data can be rebuilt properly */
|
||||
$class = 'IPS\cms\Records\RecordsTopicSync' . $database->_id;
|
||||
$class::load( $this->topic->tid )->rebuildFirstAndLastCommentData();
|
||||
if( $comments and $record->_forum_comments )
|
||||
{
|
||||
$obj = $record->recordForTopicSynch();
|
||||
$obj->rebuildFirstAndLastCommentData();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
/* If the database is on a page, go to the record */
|
||||
\IPS\Output::i()->redirect( $record->url() );
|
||||
Output::i()->redirect( $record->url() );
|
||||
}
|
||||
catch( \LogicException $e )
|
||||
catch( LogicException $e )
|
||||
{
|
||||
/* If it is NOT then go back to the topic */
|
||||
\IPS\Output::i()->redirect( $this->topic->url() );
|
||||
Output::i()->redirect( $this->topic->url() );
|
||||
}
|
||||
}
|
||||
elseif ( $comments )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=cms&module=database&controller=topic&do=comments&id={$this->topic->tid}", 'front', 'topic_copy', $this->topic->title_seo )->csrf()->setQueryString( array( 'record_id' => $record->primary_id_field, 'database_id' => $database->_id ) ) );
|
||||
Output::i()->redirect( Url::internal( "app=cms&module=database&controller=topic&do=comments&id={$this->topic->tid}", 'front', 'topic_copy', $this->topic->title_seo )->csrf()->setQueryString( array( 'record_id' => $record->primary_id_field, 'database_id' => $database->_id ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
/* If the database is on a page, go to the record */
|
||||
\IPS\Output::i()->redirect( $record->url() );
|
||||
Output::i()->redirect( $record->url() );
|
||||
}
|
||||
catch( \LogicException $e )
|
||||
catch( LogicException $e )
|
||||
{
|
||||
/* If it is NOT then go back to the topic */
|
||||
\IPS\Output::i()->redirect( $this->topic->url() );
|
||||
Output::i()->redirect( $this->topic->url() );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -319,27 +361,27 @@ class _topic extends \IPS\Dispatcher\Controller
|
||||
$fieldClass::fixedFieldFormShow( 'record_allow_comments' ) or
|
||||
$fieldClass::fixedFieldFormShow( 'record_expiry_date' ) or
|
||||
$fieldClass::fixedFieldFormShow( 'record_comment_cutoff' ) or
|
||||
\IPS\Member::loggedIn()->modPermission('can_content_edit_meta_tags') )
|
||||
Member::loggedIn()->modPermission('can_content_edit_meta_tags') )
|
||||
{
|
||||
$hasModOptions = TRUE;
|
||||
}
|
||||
|
||||
array_shift( \IPS\Output::i()->breadcrumb );
|
||||
array_shift( Output::i()->breadcrumb );
|
||||
$container = NULL;
|
||||
try
|
||||
{
|
||||
$container = $this->topic->container();
|
||||
foreach ( $container->parents() as $parent )
|
||||
{
|
||||
\IPS\Output::i()->breadcrumb[] = array( $parent->url(), $parent->_title );
|
||||
Output::i()->breadcrumb[] = array( $parent->url(), $parent->_title );
|
||||
}
|
||||
\IPS\Output::i()->breadcrumb[] = array( $container->url(), $container->_title );
|
||||
Output::i()->breadcrumb[] = array( $container->url(), $container->_title );
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
\IPS\Output::i()->breadcrumb[] = array( $this->topic->url(), $this->topic->mapped( 'title' ) );
|
||||
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack( 'copy_topic_to_database' ) );
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'copy_topic_to_database' );
|
||||
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\cms\Theme::i()->getTemplate( $database->template_form, 'cms', 'database' ), 'recordForm' ), NULL, $category, $database, $page, \IPS\Member::loggedIn()->language()->addToStack( 'copy_topic_to_database' ), $hasModOptions );
|
||||
catch ( Exception $e ) { }
|
||||
Output::i()->breadcrumb[] = array( $this->topic->url(), $this->topic->mapped( 'title' ) );
|
||||
Output::i()->breadcrumb[] = array( NULL, Member::loggedIn()->language()->addToStack( 'copy_topic_to_database' ) );
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack( 'copy_topic_to_database' );
|
||||
Output::i()->output = $form->customTemplate( array( \IPS\cms\Theme::i()->getTemplate( $database->template_form, 'cms', 'database' ), 'recordForm' ), NULL, $category, $database, $page, Member::loggedIn()->language()->addToStack( 'copy_topic_to_database' ), $hasModOptions );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -347,21 +389,24 @@ class _topic extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function comments()
|
||||
protected function comments() : void
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
$mr = new \IPS\Helpers\MultipleRedirect( \IPS\Http\Url::internal( "app=cms&module=database&controller=topic&id=" . \IPS\Request::i()->id . "&do=comments", 'front', 'topic_copy', $this->topic->title_seo )->csrf()->setQueryString( array( 'database_id' => \IPS\Request::i()->database_id, 'record_id' => \IPS\Request::i()->record_id ) ), function( $data ) {
|
||||
$database = \IPS\cms\Databases::load( \IPS\Request::i()->database_id );
|
||||
$recordClass = 'IPS\cms\Records' . \IPS\Request::i()->database_id;
|
||||
Session::i()->csrfCheck();
|
||||
|
||||
$mr = new MultipleRedirect( Url::internal( "app=cms&module=database&controller=topic&id=" . Request::i()->id . "&do=comments", 'front', 'topic_copy', $this->topic->title_seo )->csrf()->setQueryString( array( 'database_id' => Request::i()->database_id, 'record_id' => Request::i()->record_id ) ), function( $data ) {
|
||||
|
||||
/* @var Records $recordClass
|
||||
* @var Records\Comment $commentClass */
|
||||
$database = Databases::load( Request::i()->database_id );
|
||||
$recordClass = 'IPS\cms\Records' . Request::i()->database_id;
|
||||
$commentClass = $recordClass::$commentClass;
|
||||
$record = $recordClass::load( \IPS\Request::i()->record_id );
|
||||
$total = \IPS\Db::i()->select( 'COUNT(*)', 'forums_posts', array( "topic_id=? AND new_topic=? AND queued!=?", \IPS\Request::i()->id, 0, 2 ) )->first();
|
||||
$record = $recordClass::load( Request::i()->record_id );
|
||||
$total = Db::i()->select( 'COUNT(*)', 'forums_posts', array( "topic_id=? AND new_topic=? AND queued!=?", Request::i()->id, 0, 2 ) )->first();
|
||||
|
||||
$done = 0;
|
||||
foreach( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'forums_posts', array( "topic_id=? AND new_topic=? AND queued!=?", \IPS\Request::i()->id, 0, -2 ), "pid ASC", array( $data, 100 ) ), 'IPS\forums\Topic\Post' ) AS $post )
|
||||
foreach( new ActiveRecordIterator( Db::i()->select( '*', 'forums_posts', array( "topic_id=? AND new_topic=? AND queued!=?", Request::i()->id, 0, -2 ), "pid ASC", array( $data, 100 ) ), 'IPS\forums\Topic\Post' ) AS $post )
|
||||
{
|
||||
$commentClass::create( $record, $post->content(), FALSE, NULL, TRUE, $post->author(), \IPS\DateTime::create(), $post->ip_address, $post->hidden() );
|
||||
$commentClass::create( $record, $post->content(), FALSE, NULL, TRUE, $post->author(), DateTime::create(), $post->ip_address, $post->hidden() );
|
||||
$done++;
|
||||
}
|
||||
|
||||
@@ -370,40 +415,42 @@ class _topic extends \IPS\Dispatcher\Controller
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return array( $data + $done, \IPS\Member::loggedIn()->language()->addToStack( 'copying_comments' ), 100 / $total * ( $data + 100 ) );
|
||||
return array( $data + $done, Member::loggedIn()->language()->addToStack( 'copying_comments' ), 100 / $total * ( $data + 100 ) );
|
||||
|
||||
}, function() {
|
||||
$recordClass = 'IPS\cms\Records' . \IPS\Request::i()->database_id;
|
||||
$record = $recordClass::load( \IPS\Request::i()->record_id );
|
||||
|
||||
/* @var Records $recordClass */
|
||||
$recordClass = 'IPS\cms\Records' . Request::i()->database_id;
|
||||
$record = $recordClass::load( Request::i()->record_id );
|
||||
|
||||
try
|
||||
{
|
||||
\IPS\Output::i()->redirect( $record->url() );
|
||||
Output::i()->redirect( $record->url() );
|
||||
}
|
||||
catch( \LogicException $e )
|
||||
catch( LogicException $e )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\forums\Topic::load( \IPS\Request::i()->id )->url() );
|
||||
Output::i()->redirect( TopicClass::load( Request::i()->id )->url() );
|
||||
}
|
||||
} );
|
||||
|
||||
$topic = \IPS\forums\Topic::load( \IPS\Request::i()->id );
|
||||
$topic = TopicClass::load( Request::i()->id );
|
||||
|
||||
array_shift( \IPS\Output::i()->breadcrumb );
|
||||
array_shift( Output::i()->breadcrumb );
|
||||
$container = NULL;
|
||||
try
|
||||
{
|
||||
$container = $topic->container();
|
||||
foreach ( $container->parents() as $parent )
|
||||
{
|
||||
\IPS\Output::i()->breadcrumb[] = array( $parent->url(), $parent->_title );
|
||||
Output::i()->breadcrumb[] = array( $parent->url(), $parent->_title );
|
||||
}
|
||||
\IPS\Output::i()->breadcrumb[] = array( $container->url(), $container->_title );
|
||||
Output::i()->breadcrumb[] = array( $container->url(), $container->_title );
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
\IPS\Output::i()->breadcrumb[] = array( $topic->url(), $topic->mapped( 'title' ) );
|
||||
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack( 'copy_topic_to_database' ) );
|
||||
catch ( Exception $e ) { }
|
||||
Output::i()->breadcrumb[] = array( $topic->url(), $topic->mapped( 'title' ) );
|
||||
Output::i()->breadcrumb[] = array( NULL, Member::loggedIn()->language()->addToStack( 'copy_topic_to_database' ) );
|
||||
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'copying_comments' );
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core', 'front' )->genericBlock( (string) $mr, \IPS\Member::loggedIn()->language()->addToStack( 'copying_comments' ), 'ipsBox ipsPad' );
|
||||
Output::i()->title = Member::loggedIn()->language()->addToStack( 'copying_comments' );
|
||||
Output::i()->output = Theme::i()->getTemplate( 'global', 'core', 'front' )->genericBlock( (string) $mr, Member::loggedIn()->language()->addToStack( 'copying_comments' ), 'ipsBox i-padding_3' );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @brief ajax
|
||||
* @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 Pages
|
||||
* @since 13 Dec 2023
|
||||
*/
|
||||
|
||||
namespace IPS\cms\modules\front\pages;
|
||||
|
||||
use IPS\cms\Categories;
|
||||
use IPS\cms\Pages\Folder;
|
||||
use IPS\cms\Pages\Page;
|
||||
use IPS\Db;
|
||||
use IPS\Patterns\ActiveRecordIterator;
|
||||
use IPS\Theme;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* ajax
|
||||
*/
|
||||
class ajax extends \IPS\cms\modules\admin\pages\ajax
|
||||
{
|
||||
/**
|
||||
* Load navigation items
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function loadItems() : void
|
||||
{
|
||||
if( Request::i()->navType == 'folder' )
|
||||
{
|
||||
try
|
||||
{
|
||||
$folder = Folder::load( Request::i()->container );
|
||||
$items = iterator_to_array(
|
||||
new ActiveRecordIterator(
|
||||
Db::i()->select( '*', 'cms_pages', [ 'page_folder_id=?', $folder->id ] ),
|
||||
Page::class
|
||||
)
|
||||
);
|
||||
Output::i()->sendOutput( Theme::i()->getTemplate( 'widgets', 'cms', 'front' )->folderNavigationItems( $items ) );
|
||||
}
|
||||
catch( OutOfRangeException ){}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* @var Categories $containerClass */
|
||||
$containerClass = 'IPS\cms\Categories' . Request::i()->navId;
|
||||
try
|
||||
{
|
||||
$container = $containerClass::load( Request::i()->container );
|
||||
Output::i()->sendOutput( Theme::i()->getTemplate( 'widgets', 'cms', 'front' )->databaseNavigationItems( $container->getContentItems( null, null ) ) );
|
||||
}
|
||||
catch( OutOfRangeException ){}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,278 +12,52 @@
|
||||
namespace IPS\cms\modules\front\pages;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\cms\Blocks\Block;
|
||||
use IPS\cms\Pages\Page;
|
||||
use IPS\cms\Widget;
|
||||
use IPS\cms\widgets\Blocks;
|
||||
use IPS\core\modules\front\system\widgets;
|
||||
use IPS\Db;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
use IPS\Widget\Area;
|
||||
use OutOfRangeException;
|
||||
use Throwable;
|
||||
use UnderFlowException;
|
||||
use function count;
|
||||
use function defined;
|
||||
use function in_array;
|
||||
use function var_export;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* page
|
||||
*/
|
||||
class _builder extends \IPS\core\modules\front\system\widgets
|
||||
class builder extends widgets
|
||||
{
|
||||
|
||||
/**
|
||||
* Get Output For Adding A New Block
|
||||
* The widget class to use for configuration
|
||||
*
|
||||
* @return void
|
||||
* @var string
|
||||
*/
|
||||
protected function getBlock()
|
||||
{
|
||||
$key = $block = explode( "_", \IPS\Request::i()->blockID );
|
||||
|
||||
if ( isset( \IPS\Request::i()->pageID ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach ( \IPS\Db::i()->select( '*', 'cms_page_widget_areas', array( 'area_page_id=?', \IPS\Request::i()->pageID ) ) as $item )
|
||||
{
|
||||
$blocks = json_decode( $item['area_widgets'], TRUE );
|
||||
|
||||
foreach( $blocks as $block )
|
||||
{
|
||||
if( $block['key'] == $key[2] AND $block['unique'] == $key[3] )
|
||||
{
|
||||
if ( isset( $block['app'] ) and $block['app'] == $key[1] )
|
||||
{
|
||||
$widget = \IPS\Widget::load( \IPS\Application::load( $block['app'] ), $block['key'], $block['unique'], $block['configuration'], null, \IPS\Request::i()->orientation );
|
||||
}
|
||||
elseif ( isset( $block['plugin'] ) and $block['plugin'] == $key[1] )
|
||||
{
|
||||
$widget = \IPS\Widget::load( \IPS\Plugin::load( $block['plugin'] ), $block['key'], $block['unique'], $block['configuration'], null, \IPS\Request::i()->orientation );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch ( \UnderflowException $e ) { }
|
||||
protected string $widgetClass = Widget::class;
|
||||
|
||||
/* Make sure the current page is set so the widgets have database/page scope */
|
||||
\IPS\cms\Pages\Page::$currentPage = \IPS\cms\Pages\Page::load( \IPS\Request::i()->pageID );
|
||||
|
||||
/* Have we got a database for this page? */
|
||||
$database = \IPS\cms\Pages\Page::$currentPage->getDatabase();
|
||||
|
||||
if ( $database )
|
||||
{
|
||||
\IPS\cms\Databases\Dispatcher::i()->setDatabase( $database->id );
|
||||
}
|
||||
}
|
||||
|
||||
if ( !isset( $widget ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$widget = \IPS\Widget::load( \IPS\Application::load( $key[1] ), $key[2], $key[3], array(), null, \IPS\Request::i()->orientation );
|
||||
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
$widget = \IPS\Widget::load( \IPS\Plugin::load( $key[1] ), $key[2], $key[3], array(), null, \IPS\Request::i()->orientation );
|
||||
}
|
||||
}
|
||||
|
||||
$output = (string) $widget;
|
||||
|
||||
\IPS\Output::i()->output = ( $output ) ? $output : \IPS\Theme::i()->getTemplate( 'widgets', 'core', 'front' )->blankWidget( $widget );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Configuration
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function getConfiguration()
|
||||
{
|
||||
/* Standard widget area, allow the core stuff to handle this */
|
||||
if( \in_array( \IPS\Request::i()->area, array( 'sidebar', 'header', 'footer' ) ) )
|
||||
{
|
||||
return parent::getConfiguration();
|
||||
}
|
||||
|
||||
$key = explode( "_", \IPS\Request::i()->block );
|
||||
$blocks = array( 'area_widgets' => NULL );
|
||||
|
||||
/* CMS only stuff */
|
||||
try
|
||||
{
|
||||
$blocks = \IPS\Db::i()->select( '*', 'cms_page_widget_areas', array( 'area_page_id=? AND area_area=?', \IPS\Request::i()->pageID, \IPS\Request::i()->pageArea ) )->first();
|
||||
|
||||
$where = ( $key[0] ) == 'app' ? '`key`=? AND `app`=?' : '`key`=? AND `plugin`=?';
|
||||
$widgetMaster = \IPS\Db::i()->select( '*', 'core_widgets', array( $where, $key[2], $key[1] ) )->first();
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
{
|
||||
}
|
||||
|
||||
$blocks = json_decode( $blocks['area_widgets'], TRUE );
|
||||
$widget = NULL;
|
||||
|
||||
if( !empty( $blocks ) )
|
||||
{
|
||||
foreach ( $blocks as $k => $block )
|
||||
{
|
||||
if ( $block['key'] == $key[2] AND $block['unique'] == $key[3] )
|
||||
{
|
||||
if ( isset( $block['app'] ) and $block['app'] == $key[1] )
|
||||
{
|
||||
$widget = \IPS\Widget::load( \IPS\Application::load( $block['app'] ), $block['key'], $block['unique'], $block['configuration'] );
|
||||
$widget->menuStyle = $widgetMaster['menu_style'];
|
||||
}
|
||||
elseif ( isset( $block['plugin'] ) and $block['plugin'] == $key[1] )
|
||||
{
|
||||
$widget = \IPS\Widget::load( \IPS\Plugin::load( $block['plugin'] ), $block['key'], $block['unique'], $block['configuration'] );
|
||||
$widget->menuStyle = $widgetMaster['menu_style'];
|
||||
}
|
||||
}
|
||||
|
||||
if( $widget !== NULL AND method_exists( $widget, 'configuration' ) )
|
||||
{
|
||||
$form = new \IPS\Helpers\Form( 'form', 'saveSettings' );
|
||||
if ( $widget->configuration( $form ) !== NULL )
|
||||
{
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
if ( method_exists( $widget, 'preConfig' ) )
|
||||
{
|
||||
$values = $widget->preConfig( $values );
|
||||
}
|
||||
|
||||
/* Special advanced builder stuff */
|
||||
if ( \in_array( 'IPS\Widget\Builder', class_implements( $widget ) ) )
|
||||
{
|
||||
if( isset( $values['widget_adv__background_custom_image'] ) and $values['widget_adv__background_custom_image'] )
|
||||
{
|
||||
$values['widget_adv__background_custom_image'] = (string) $values['widget_adv__background_custom_image'];
|
||||
}
|
||||
}
|
||||
|
||||
$blocks[ $k ]['configuration'] = $values;
|
||||
\IPS\Db::i()->insert( 'cms_page_widget_areas', array( 'area_page_id' => \IPS\Request::i()->pageID, 'area_area' => \IPS\Request::i()->pageArea, 'area_widgets' => json_encode( $blocks ) ), TRUE );
|
||||
|
||||
/* Reindex the page any time the blocks are updated */
|
||||
try
|
||||
{
|
||||
\IPS\Content\Search\Index::i()->index( \IPS\cms\Pages\PageItem::load( \IPS\Request::i()->pageID ) );
|
||||
}
|
||||
catch( \OutOfRangeException ){}
|
||||
|
||||
\IPS\Output::i()->json( 'OK' );
|
||||
}
|
||||
\IPS\Output::i()->output = $widget->configuration()->customTemplate( array( \IPS\Theme::i()->getTemplate( 'widgets', 'core' ), 'formTemplate' ), $widget );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reorder Blocks
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function saveOrder()
|
||||
protected function saveOrder() : void
|
||||
{
|
||||
$newOrder = array();
|
||||
$seen = array();
|
||||
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
try
|
||||
{
|
||||
$currentConfig = \IPS\Db::i()->select( '*', 'cms_page_widget_areas', array( 'area_page_id=? AND area_area=?', \IPS\Request::i()->pageID, \IPS\Request::i()->area ) )->first();
|
||||
$widgets = json_decode( $currentConfig['area_widgets'], TRUE );
|
||||
if( !is_countable( $widgets ) )
|
||||
{
|
||||
throw new \UnderflowException;
|
||||
}
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
{
|
||||
$widgets = array();
|
||||
}
|
||||
|
||||
/* Loop over the new order and merge in current blocks so we don't lose config */
|
||||
if ( isset ( \IPS\Request::i()->order ) )
|
||||
{
|
||||
foreach ( \IPS\Request::i()->order as $block )
|
||||
{
|
||||
$block = explode( "_", $block );
|
||||
|
||||
$added = FALSE;
|
||||
foreach( $widgets as $widget )
|
||||
{
|
||||
if ( $widget['key'] == $block[2] and $widget['unique'] == $block[3] )
|
||||
{
|
||||
$seen[] = $widget['unique'];
|
||||
$newOrder[] = $widget;
|
||||
$added = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( !$added )
|
||||
{
|
||||
$newBlock = array();
|
||||
|
||||
if ( $block[0] == 'app' )
|
||||
{
|
||||
$newBlock['app'] = $block[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
$newBlock['plugin'] = $block[1];
|
||||
}
|
||||
|
||||
$newBlock['key'] = $block[2];
|
||||
$newBlock['unique'] = $block[3];
|
||||
$newBlock['configuration'] = array();
|
||||
|
||||
/* Make sure this widget doesn't have configuration in another area */
|
||||
$newBlock['configuration'] = \IPS\cms\Widget::getConfiguration( $newBlock['unique'] );
|
||||
|
||||
$seen[] = $block[3];
|
||||
$newOrder[] = $newBlock;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Anything to update? */
|
||||
if ( \count( $widgets ) > \count( $newOrder ) )
|
||||
{
|
||||
/* No items left in area, or one has been removed */
|
||||
foreach( $widgets as $widget )
|
||||
{
|
||||
/* If we haven't seen this widget, it's been removed, so add to trash */
|
||||
if ( ! \in_array( $widget['unique'], $seen ) )
|
||||
{
|
||||
\IPS\Widget::trash( $widget['unique'], $widget );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check core_widget_areas to ensure that the block wasn't added there */
|
||||
if ( isset( \IPS\Request::i()->exclude ) and ! empty( \IPS\Request::i()->exclude ) )
|
||||
{
|
||||
$bits = explode( "_", \IPS\Request::i()->exclude );
|
||||
$this->_checkAndDeleteFromCoreWidgets( $bits[3], $seen );
|
||||
}
|
||||
|
||||
/* Expire Caches so up to date information displays */
|
||||
\IPS\Widget::deleteCaches();
|
||||
|
||||
/* Save to database */
|
||||
$orientation = ( isset( \IPS\Request::i()->orientation ) and \IPS\Request::i()->orientation === 'vertical' ) ? 'vertical' : 'horizontal';
|
||||
\IPS\Db::i()->replace( 'cms_page_widget_areas', array( 'area_orientation' => $orientation, 'area_page_id' => \IPS\Request::i()->pageID, 'area_widgets' => json_encode( $newOrder ), 'area_area' => \IPS\Request::i()->area ) );
|
||||
|
||||
/* Reindex the page any time the blocks are updated */
|
||||
try
|
||||
{
|
||||
\IPS\Content\Search\Index::i()->index( \IPS\cms\Pages\PageItem::load( \IPS\Request::i()->pageID ) );
|
||||
}
|
||||
catch( \OutOfRangeException ){}
|
||||
|
||||
\IPS\cms\Pages\Page::load( \IPS\Request::i()->pageID )->postWidgetOrderSave();
|
||||
parent::saveOrder();
|
||||
$page = Page::load( Request::i()->pageID );
|
||||
$page->postSaveArea();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -291,18 +65,18 @@ class _builder extends \IPS\core\modules\front\system\widgets
|
||||
* It may be that the CMS JS mixin doesn't load so the core ajax URLs are used (system/widgets.php) and not the cms widget (page/builder.php).
|
||||
* This method ensures that any widgets in the core table are removed
|
||||
*
|
||||
* @param string $uniqueId The unique key of the widget (eg: wzsj1233)
|
||||
* @param array $widgets Current widgets (eg from core_widget_areas.widgets (json decoded))
|
||||
* @param string $uniqueId The unique key of the widget (eg: wzsj1233)
|
||||
* @param array $widgets Current widgets (eg from core_widget_areas.widgets (json decoded))
|
||||
* @return bool True if something removed, false if not
|
||||
*/
|
||||
protected function _checkAndDeleteFromCoreWidgets( $uniqueId, $widgets )
|
||||
protected function _checkAndDeleteFromCoreWidgets( string $uniqueId, array $widgets ): bool
|
||||
{
|
||||
if ( ! \in_array( $uniqueId, $widgets ) )
|
||||
if ( ! in_array( $uniqueId, $widgets ) )
|
||||
{
|
||||
/* This widget hasn't been seen, so it isn't in the cms table */
|
||||
try
|
||||
{
|
||||
$cmsWidget = \IPS\Db::i()->select( '*', 'core_widget_areas', array( 'app=? and module=? and controller=? and area=?', 'cms', 'pages', 'page', \IPS\Request::i()->area ) )->first();
|
||||
$cmsWidget = Db::i()->select( '*', 'core_widget_areas', array( 'app=? and module=? and controller=? and area=?', 'cms', 'pages', 'page', Request::i()->area ) )->first();
|
||||
$cmsWidgets = json_decode( $cmsWidget['widgets'], TRUE );
|
||||
$newWidgets = array();
|
||||
|
||||
@@ -315,23 +89,86 @@ class _builder extends \IPS\core\modules\front\system\widgets
|
||||
}
|
||||
|
||||
/* Anything to save? */
|
||||
if ( \count( $newWidgets ) )
|
||||
if ( count( $newWidgets ) )
|
||||
{
|
||||
\IPS\Db::i()->replace( 'core_widget_areas', array( 'app' => 'cms', 'module' => 'pages', 'controller' => 'page', 'widgets' => json_encode( $newWidgets ), 'area' => \IPS\Request::i()->area ) );
|
||||
Db::i()->replace( 'core_widget_areas', array( 'app' => 'cms', 'module' => 'pages', 'controller' => 'page', 'widgets' => json_encode( $newWidgets ), 'area' => Request::i()->area ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Just remove the entire row */
|
||||
\IPS\Db::i()->delete( 'core_widget_areas', array( 'app=? and module=? and controller=? and area=?', 'cms', 'pages', 'page', \IPS\Request::i()->area ) );
|
||||
Db::i()->delete( 'core_widget_areas', array( 'app=? and module=? and controller=? and area=?', 'cms', 'pages', 'page', Request::i()->area ) );
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
catch( \UnderFlowException $ex )
|
||||
catch( UnderFlowException $ex )
|
||||
{
|
||||
/* Well, it isn't there either... */
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array containing all the areas in this page
|
||||
*
|
||||
* @param string|null $area The area to filter by; by default (null) it will get all areas
|
||||
*
|
||||
* @return Area[] Returns an array mapping the widget areas to the widgets in that area
|
||||
*/
|
||||
public function getAreasFromDatabase( ?string $area=null ) : array
|
||||
{
|
||||
$page = Page::load( Request::i()->pageID );
|
||||
return $page->getAreasFromDatabase( $area );
|
||||
}
|
||||
|
||||
/**
|
||||
* Save an area to the database and link it to the page
|
||||
*
|
||||
* @param Area $area
|
||||
* @return void
|
||||
*/
|
||||
public function saveArea( Area $area ) : void
|
||||
{
|
||||
$page = Page::load( Request::i()->pageID );
|
||||
$page->saveArea( $area );
|
||||
|
||||
/* Clear caches */
|
||||
Widget::deleteCaches();
|
||||
}
|
||||
|
||||
/**
|
||||
* Output the content of a custom block
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getCustomBlockContent() : void
|
||||
{
|
||||
try
|
||||
{
|
||||
$block = Block::load( Request::i()->id );
|
||||
|
||||
try
|
||||
{
|
||||
$widget = $block->widget();
|
||||
}
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
$widget = new Blocks( "", ['cms_widget_custom_block' => $block->key] );
|
||||
}
|
||||
Output::i()->json( [ "content" => (string) $widget, "configuration" => $widget->dataAttributes(), 'block_key' => $block->key ], 200 );
|
||||
}
|
||||
catch ( UnderFlowException|OutOfRangeException $e )
|
||||
{
|
||||
Output::i()->json( [ "message" => "could not find block" ], 404 );
|
||||
}
|
||||
catch ( Throwable $e )
|
||||
{
|
||||
if ( \IPS\IN_DEV )
|
||||
{
|
||||
Output::i()->json( [ "error" => var_export( $e, true ) ], 500 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,24 +12,39 @@
|
||||
namespace IPS\cms\modules\front\pages;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\cms\Databases\Dispatcher;
|
||||
use IPS\cms\Pages\Page as PageClass;
|
||||
use IPS\Dispatcher\Controller;
|
||||
use IPS\Http\Url;
|
||||
use IPS\IPS;
|
||||
use IPS\Log;
|
||||
use IPS\Output;
|
||||
use IPS\Request;
|
||||
use IPS\Session;
|
||||
use IPS\Settings;
|
||||
use OutOfRangeException;
|
||||
use ParseError;
|
||||
use function defined;
|
||||
use function func_get_args;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* page
|
||||
*/
|
||||
class _page extends \IPS\Dispatcher\Controller
|
||||
class page extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* Determine which method to load
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function manage()
|
||||
public function manage() : void
|
||||
{
|
||||
$this->view();
|
||||
}
|
||||
@@ -39,46 +54,46 @@ class _page extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function view()
|
||||
protected function view() : void
|
||||
{
|
||||
$page = $this->getPage();
|
||||
$page = $this::getPage();
|
||||
|
||||
/* Database specific checks */
|
||||
if ( isset( \IPS\Request::i()->advancedSearchForm ) AND isset( \IPS\Request::i()->d ) )
|
||||
if ( isset( Request::i()->advancedSearchForm ) AND isset( Request::i()->d ) )
|
||||
{
|
||||
/* showTableSearchForm just triggers __call which returns the database dispatcher HTML as we
|
||||
* do not want the page content around the actual database */
|
||||
\IPS\Output::i()->output = $this->showTableSearchForm();
|
||||
Output::i()->output = $this->showTableSearchForm();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( \IPS\Request::i()->path == $page->full_path )
|
||||
if ( Request::i()->path == $page->full_path )
|
||||
{
|
||||
/* Are we using Friendly URL's at all? */
|
||||
if ( \IPS\Settings::i()->use_friendly_urls )
|
||||
if ( Settings::i()->use_friendly_urls )
|
||||
{
|
||||
/* Did we have a trailing slash? */
|
||||
if ( \IPS\Settings::i()->htaccess_mod_rewrite and mb_substr( \IPS\Request::i()->url()->data[ \IPS\Http\Url::COMPONENT_PATH ], -1 ) != '/' )
|
||||
if ( Settings::i()->htaccess_mod_rewrite and mb_substr( Request::i()->url()->data[ Url::COMPONENT_PATH ], -1 ) != '/' )
|
||||
{
|
||||
$url = $page->url();
|
||||
|
||||
foreach( \IPS\Request::i()->url()->queryString as $k => $v )
|
||||
foreach( Request::i()->url()->queryString as $k => $v )
|
||||
{
|
||||
$url = $url->setQueryString( $k, $v );
|
||||
}
|
||||
|
||||
if ( ! empty( \IPS\Request::i()->url()->fragment ) )
|
||||
if ( ! empty( Request::i()->url()->fragment ) )
|
||||
{
|
||||
$url = $url->setFragment( \IPS\Request::i()->url()->fragment );
|
||||
$url = $url->setFragment( Request::i()->url()->fragment );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( $url, NULL, 301 );
|
||||
Output::i()->redirect( $url );
|
||||
}
|
||||
else if ( ! \IPS\Settings::i()->htaccess_mod_rewrite and ! mb_strstr( \IPS\Request::i()->url()->data[ \IPS\Http\Url::COMPONENT_QUERY ], $page->url()->data[ \IPS\Http\Url::COMPONENT_QUERY ] ) )
|
||||
else if ( ! Settings::i()->htaccess_mod_rewrite and ! mb_strstr( Request::i()->url()->data[ Url::COMPONENT_QUERY ], $page->url()->data[ Url::COMPONENT_QUERY ] ) )
|
||||
{
|
||||
$url = $page->url();
|
||||
|
||||
foreach( \IPS\Request::i()->url()->queryString as $k => $v )
|
||||
foreach( Request::i()->url()->queryString as $k => $v )
|
||||
{
|
||||
if ( mb_substr( $k, 0, 1 ) == '/' and mb_substr( $k, -1 ) != '/' )
|
||||
{
|
||||
@@ -88,79 +103,79 @@ class _page extends \IPS\Dispatcher\Controller
|
||||
|
||||
$url = $url->setQueryString( $k, $v );
|
||||
|
||||
if ( ! empty( \IPS\Request::i()->url()->fragment ) )
|
||||
if ( ! empty( Request::i()->url()->fragment ) )
|
||||
{
|
||||
$url = $url->setFragment( \IPS\Request::i()->url()->fragment );
|
||||
$url = $url->setFragment( Request::i()->url()->fragment );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( $url, NULL, 301 );
|
||||
Output::i()->redirect( $url );
|
||||
}
|
||||
}
|
||||
|
||||
/* Just viewing this page, no database categories or records */
|
||||
$permissions = $page->permissions();
|
||||
\IPS\Session::i()->setLocation( $page->url(), explode( ",", $permissions['perm_view'] ), 'loc_cms_viewing_page', array( 'cms_page_' . $page->_id => TRUE ) );
|
||||
Session::i()->setLocation( $page->url(), explode( ",", $permissions['perm_view'] ), 'loc_cms_viewing_page', array( 'cms_page_' . $page->_id => TRUE ) );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$page->output();
|
||||
}
|
||||
catch ( \ParseError $e )
|
||||
catch ( ParseError $e )
|
||||
{
|
||||
\IPS\Log::log( $e, 'page_error' );
|
||||
\IPS\Output::i()->error( 'content_err_page_500', '2T187/4', 500, 'content_err_page_500_admin', array(), $e );
|
||||
Log::log( $e, 'page_error' );
|
||||
Output::i()->error( 'content_err_page_500', '2T187/4', 500, 'content_err_page_500_admin', array(), $e );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current page
|
||||
*
|
||||
* @return \IPS\cms\Pages\Page
|
||||
* @return PageClass|null
|
||||
*/
|
||||
public function getPage()
|
||||
public static function getPage(): ?PageClass
|
||||
{
|
||||
$page = null;
|
||||
if ( isset( \IPS\Request::i()->page_id ) )
|
||||
if ( isset( Request::i()->page_id ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$page = \IPS\cms\Pages\Page::load( \IPS\Request::i()->page_id );
|
||||
$page = PageClass::load( Request::i()->page_id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'content_err_page_404', '2T187/1', 404, '' );
|
||||
Output::i()->error( 'content_err_page_404', '2T187/1', 404, '' );
|
||||
}
|
||||
}
|
||||
else if ( isset( \IPS\Request::i()->path ) AND \IPS\Request::i()->path != '/' )
|
||||
else if ( isset( Request::i()->path ) AND Request::i()->path != '/' )
|
||||
{
|
||||
/* Sort out pagination for pages */
|
||||
list( $path, $pageNumber ) = \IPS\cms\Pages\Page::getStrippedPagePath( \IPS\Request::i()->path );
|
||||
if( $pageNumber AND !\IPS\Request::i()->page )
|
||||
list( $path, $pageNumber ) = PageClass::getStrippedPagePath( Request::i()->path );
|
||||
if( $pageNumber AND !Request::i()->page )
|
||||
{
|
||||
\IPS\Request::i()->page = $pageNumber;
|
||||
Request::i()->page = $pageNumber;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$page = \IPS\cms\Pages\Page::loadFromPath( $path );
|
||||
$page = PageClass::loadFromPath( $path );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
try
|
||||
{
|
||||
$page = \IPS\cms\Pages\Page::getUrlFromHistory( \IPS\Request::i()->path, ( isset( \IPS\Request::i()->url()->data['query'] ) ? \IPS\Request::i()->url()->data['query'] : NULL ) );
|
||||
$page = PageClass::getUrlFromHistory( Request::i()->path, ( isset( Request::i()->url()->data['query'] ) ? Request::i()->url()->data['query'] : NULL ) );
|
||||
|
||||
if( (string) $page == (string) \IPS\Request::i()->url() )
|
||||
if( (string) $page == (string) Request::i()->url() )
|
||||
{
|
||||
\IPS\Output::i()->error( 'content_err_page_404', '2T187/3', 404, '' );
|
||||
Output::i()->error( 'content_err_page_404', '2T187/3', 404, '' );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( $page, NULL, 301 );
|
||||
Output::i()->redirect( $page );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
catch( OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'content_err_page_404', '2T187/2', 404, '' );
|
||||
Output::i()->error( 'content_err_page_404', '2T187/2', 404, '' );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -168,31 +183,31 @@ class _page extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
try
|
||||
{
|
||||
$page = \IPS\cms\Pages\Page::getDefaultPage();
|
||||
$page = PageClass::getDefaultPage();
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'content_err_page_404', '2T257/1', 404, '' );
|
||||
Output::i()->error( 'content_err_page_404', '2T257/1', 404, '' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $page === NULL )
|
||||
{
|
||||
\IPS\Output::i()->error( 'content_err_page_404', '2T257/2', 404, '' );
|
||||
Output::i()->error( 'content_err_page_404', '2T257/2', 404, '' );
|
||||
}
|
||||
|
||||
if ( ! $page->can('view') )
|
||||
{
|
||||
\IPS\Output::i()->error( 'content_err_page_403', '2T187/3', 403, '' );
|
||||
Output::i()->error( 'content_err_page_403', '2T187/3', 403, '' );
|
||||
}
|
||||
|
||||
if ( \IPS\IPS::classUsesTrait( $page->item(), 'IPS\Content\ViewUpdates' ) )
|
||||
if ( IPS::classUsesTrait( $page->item(), 'IPS\Content\ViewUpdates' ) )
|
||||
{
|
||||
$page->item()->updateViews();
|
||||
}
|
||||
|
||||
/* Set the current page, so other blocks, DBs, etc don't have to figure out where they are */
|
||||
\IPS\cms\Pages\Page::$currentPage = $page;
|
||||
PageClass::$currentPage = $page;
|
||||
|
||||
return $page;
|
||||
}
|
||||
@@ -200,34 +215,37 @@ class _page extends \IPS\Dispatcher\Controller
|
||||
/**
|
||||
* Capture database specific things
|
||||
*
|
||||
* @param string $method Desired method
|
||||
* @param array $args Arguments
|
||||
* @return void
|
||||
* @param string $method Desired method
|
||||
* @param array $args Arguments
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call( $method, $args )
|
||||
public function __call( string $method, array $args ) : mixed
|
||||
{
|
||||
$page = $this->getPage();
|
||||
$page = $this::getPage();
|
||||
$page->setTheme();
|
||||
$databaseId = ( isset( \IPS\Request::i()->d ) ) ? \IPS\Request::i()->d : $page->getDatabase()->_id;
|
||||
$databaseId = ( isset( Request::i()->d ) ) ? Request::i()->d : $page->getDatabase()->_id;
|
||||
|
||||
if ( $databaseId !== NULL )
|
||||
{
|
||||
try
|
||||
{
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
if ( Request::i()->isAjax() )
|
||||
{
|
||||
return \IPS\cms\Databases\Dispatcher::i()->setDatabase( $databaseId )->run();
|
||||
Dispatcher::i()->setDatabase( $databaseId )->run();
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
$page->output();
|
||||
}
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
catch( OutOfRangeException $e )
|
||||
{
|
||||
\IPS\Output::i()->error( 'content_err_page_404', '2T257/3', 404, '' );
|
||||
Output::i()->error( 'content_err_page_404', '2T257/3', 404, '' );
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -235,8 +253,8 @@ class _page extends \IPS\Dispatcher\Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function embed()
|
||||
protected function embed() : void
|
||||
{
|
||||
return $this->__call( 'embed', \func_get_args() );
|
||||
$this->__call( 'embed', func_get_args() );
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user