Files
IPB/applications/core/modules/admin/developer/acprestrictions.php
T
2025-12-19 16:27:35 -08:00

379 lines
12 KiB
PHP

<?php
/**
* @brief acprestrictions
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @since 31 Jan 2024
*/
namespace IPS\core\modules\admin\developer;
use IPS\Developer\Controller;
use IPS\Helpers\Form;
use IPS\Helpers\Form\Text;
use IPS\Helpers\Tree\Tree;
use IPS\Http\Url;
use IPS\Member;
use IPS\Output;
use IPS\Request;
use IPS\Session;
use IPS\Theme;
use function defined;
use const IPS\ROOT_PATH;
/* 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;
}
/**
* acprestrictions
*/
class acprestrictions extends Controller
{
/**
* @var bool
*/
public static bool $csrfProtected = true;
/**
* @var array|null
*/
protected ?array $modules = null;
/**
* @var array|null
*/
protected ?array $restrictions = null;
/**
* ...
*
* @return void
*/
protected function manage() : void
{
$this->modules = $this->_getModules();
$this->url = Url::internal( "app=core&module=developer&controller=acprestrictions&appKey={$this->application->directory}" );
$this->restrictions = $this->_getJson( ROOT_PATH . "/applications/{$this->application->directory}/data/acprestrictions.json" );
$appKey = $this->application->directory;
/* Display the table */
$tree = new Tree( $this->url, 'dev_acprestrictions', array( $this, 'restrictionsGetRoots' ), array( $this, 'restrictionsGetRow' ),
function ( $k )
{
if ( mb_substr( $k, 0, 1 ) === 'M' )
{
return NULL;
}
else
{
return 'M' . mb_substr( $k, 1, mb_strpos( $k, '-' ) - 1 );
}
},
array( $this, 'restrictionsGetchildren' ),
NULL,
FALSE,
TRUE,
TRUE
);
Output::i()->output = (string) $tree;
}
/**
* @return void
*/
protected function reorder() : void
{
Session::i()->csrfCheck();
/* Figure out the items we are reordering, we would only be reordering a single group */
$newOrder = array();
$position = 1;
foreach( Request::i()->ajax_order as $i => $parent )
{
if( strpos( $i, '~' ) !== FALSE )
{
if( !isset( $newOrder[ $parent ] ) )
{
$newOrder[ $parent ] = array();
}
$newOrder[ $parent ][ $i ] = $position++;
}
}
foreach( $newOrder as $groupKey => $order )
{
if( isset( Request::i()->ajax_order[ $groupKey ] ) )
{
$moduleKey = Request::i()->ajax_order[ $groupKey ];
/* Sort */
uasort( $this->restrictions[ $moduleKey ][ $groupKey ], function( $a, $b ) use ( $order ) {
return ( isset( $order[ str_replace( '_', '~', $a ) ] ) ? $order[ str_replace( '_', '~', $a ) ] : 0 ) - ( isset( $order[ str_replace( '_', '~', $b ) ] ) ? $order[ str_replace( '_', '~', $b ) ] : 0 );
});
}
}
/* Write */
$this->_writeJson( ROOT_PATH . "/applications/{$this->application->directory}/data/acprestrictions.json", $this->restrictions );
}
/**
* Restrictions: Get Root Rows
*
* @return array
*/
public function restrictionsGetRoots() : array
{
$rows = array();
if( !empty( $this->modules['admin'] ) )
{
foreach ( $this->modules['admin'] as $k => $module )
{
if ( empty( $module['protected'] ) )
{
$rows[ $k ] = $this->_restrictionsModuleRow( $this->url, $k, $this->restrictions, FALSE );
}
}
}
return $rows;
}
/**
* Restrictions: Get Individual Row
*
* @param string $k ID
* @param bool $root Is root row?
* @return string
*/
public function restrictionsGetRow( string $k, bool $root ) : string
{
if ( mb_substr( $k, 0, 1 ) === 'M' )
{
return $this->_restrictionsModuleRow( $this->url, mb_substr( $k, 1 ), $this->restrictions, $root );
}
else
{
$moduleKey = mb_substr( $k, 1, mb_strpos( $k, '-' ) - 1 );
$groupKey = mb_substr( $k, mb_strpos( $k, '-' ) + 1 );
return $this->_restrictionsGroupRow( $this->url, $groupKey, $moduleKey, $this->restrictions[ $moduleKey ][ $groupKey ], $root );
}
}
/**
* Restrictions: Get Child Rows
*
* @param string $k ID
* @return array
*/
public function restrictionsGetChildren( string $k ) : array
{
$rows = array();
if ( mb_substr( $k, 0, 1 ) === 'M' )
{
$k = mb_substr( $k, 1 );
foreach ( $this->restrictions[ $k ] as $groupKey => $r )
{
$rows[ $groupKey ] = $this->_restrictionsGroupRow( $this->url, $groupKey, $k, $r, FALSE );
}
}
else
{
$moduleKey = mb_substr( $k, 1, mb_strpos( $k, '-' ) - 1 );
$groupKey = mb_substr( $k, mb_strpos( $k, '-' ) + 1 );
$pos = 0;
foreach ( $this->restrictions[ $moduleKey ][ $groupKey ] as $rKey )
{
$lang = "r__{$rKey}";
$rows[ str_replace( '_', '~', $rKey ) ] = Theme::i()->getTemplate( 'trees' )->row( $this->url, $rKey, Member::loggedIn()->language()->addToStack( $lang ), FALSE, array(
'delete' => array(
'icon' => 'times-circle',
'title' => 'delete',
'link' => Url::internal( "app=core&module=developer&controller=acprestrictions&appKey={$this->application->directory}&do=restrictionRowDelete&module_key={$moduleKey}&group={$groupKey}&id={$rKey}" ),
'data' => array( 'delete' => '' )
)
), $rKey, NULL, ++$pos );
}
}
return $rows;
}
/**
* Get Module Row
*
* @param string|Url $url URL
* @param string $k Key
* @param array $restrictions Restrictions JSON
* @param bool $root As root?
* @return string
*/
protected function _restrictionsModuleRow( string|Url $url, string $k, array $restrictions, bool $root ) : string
{
return Theme::i()->getTemplate( 'trees' )->row( $url, 'M'.$k, $k, isset( $restrictions[ $k ] ), array(
'add' => array(
'icon' => 'plus-circle',
'title' => 'acprestrictions_addgroup',
'link' => Url::internal( "app=core&module=developer&controller=acprestrictions&appKey={$this->application->directory}&do=restrictionGroupForm&module_key={$k}&id=0" ),
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => Member::loggedIn()->language()->addToStack('acprestrictions_addgroup') )
)
), '', NULL, NULL, $root );
}
/**
* Get Group Row
*
* @param string|Url $url URL
* @param string $groupKey Key
* @param string $moduleKey Module Key
* @param array $r Rows in this group
* @param bool $root As root?
* @return string
*/
protected function _restrictionsGroupRow( string|Url $url, string $groupKey, string $moduleKey, array $r, bool $root ) : string
{
$lang = "r__{$groupKey}";
return Theme::i()->getTemplate( 'trees' )->row( $url, "G{$moduleKey}-{$groupKey}", Member::loggedIn()->language()->addToStack( $lang ), !empty( $r ), array(
'add' => array(
'icon' => 'plus-circle',
'title' => 'acprestrictions_addrow',
'link' => Url::internal( "app=core&module=developer&controller=acprestrictions&appKey={$this->application->directory}&do=restrictionRowForm&module_key={$moduleKey}&group={$groupKey}" ),
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => Member::loggedIn()->language()->addToStack('acprestrictions_addrow') )
),
'edit' => array(
'icon' => 'pencil',
'title' => 'edit',
'link' => Url::internal( "app=core&module=developer&controller=acprestrictions&appKey={$this->application->directory}&do=restrictionGroupForm&module_key={$moduleKey}&id={$groupKey}" ),
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => Member::loggedIn()->language()->addToStack('edit') ),
'hotkey'=> 'e'
),
'delete'=> array(
'icon' => 'times-circle',
'title' => 'delete',
'link' => Url::internal( "app=core&module=developer&controller=acprestrictions&appKey={$this->application->directory}&do=restrictionGroupDelete&module_key={$moduleKey}&id={$groupKey}" ),
'data' => array( 'delete' => '' )
)
), '', NULL, NULL, $root );
}
/**
* Restriction Group Form
*
* @return void
*/
public function restrictionGroupForm() : void
{
/* Get restriction data */
$restrictions = $this->_getJson( ROOT_PATH . "/applications/{$this->application->directory}/data/acprestrictions.json" );
/* Load module */
$module = $this->_loadModule();
/* Do we have a default value? */
$current = NULL;
if ( Request::i()->id and isset( $restrictions[ $module->key ][ Request::i()->id ] ) )
{
$current = Request::i()->id;
}
/* Build Form */
$form = new Form();
$form->add( new Text( 'acprestrictions_groupkey', $current ?: '', TRUE ) );
/* Handle submissions */
if ( $values = $form->values() )
{
$rows = array();
if ( $current !== NULL )
{
$rows = $restrictions[ $module->key ][ $current ];
unset( $restrictions[ $module->key ][ $current ] );
}
$restrictions[ $module->key ][ $values['acprestrictions_groupkey'] ] = $rows;
$this->_writeJson( ROOT_PATH . "/applications/{$this->application->directory}/data/acprestrictions.json", $restrictions );
Output::i()->redirect( Url::internal( "app=core&module=developer&controller=acprestrictions&appKey={$this->application->directory}&root=M{$module->key}" ) );
}
/* Display */
Output::i()->output = Theme::i()->getTemplate( 'global' )->block( 'acprestrictions_addgroup', $form, FALSE );
}
/**
* Delete Restriction Group
*
* @return void
*/
public function restrictionGroupDelete() : void
{
/* Make sure the user confirmed the deletion */
Request::i()->confirmedDelete();
$restrictions = $this->_getJson( ROOT_PATH . "/applications/{$this->application->directory}/data/acprestrictions.json" );
$module = $this->_loadModule();
if( isset( $restrictions[ $module->key ][ Request::i()->id ] ) )
{
unset( $restrictions[ $module->key ][ Request::i()->id ] );
$this->_writeJson( ROOT_PATH . "/applications/{$this->application->directory}/data/acprestrictions.json", $restrictions );
}
Output::i()->redirect( Url::internal( "app=core&module=developer&controller=acprestrictions&appKey={$this->application->directory}&root=M{$module->key}" ) );
}
/**
* Restriction Row Form
*
* @return void
*/
protected function restrictionRowForm() : void
{
$module = $this->_loadModule();
$group = Request::i()->group;
$form = new Form();
$form->add( new Text( 'acprestrictions_rowkey', NULL, TRUE ) );
if ( $values = $form->values() )
{
$restrictions = $this->_getJson( ROOT_PATH . "/applications/{$this->application->directory}/data/acprestrictions.json" );
$restrictions[ $module->key ][ $group ][ $values['acprestrictions_rowkey'] ] = $values['acprestrictions_rowkey'];
$this->_writeJson( ROOT_PATH . "/applications/{$this->application->directory}/data/acprestrictions.json", $restrictions );
Output::i()->redirect( Url::internal( "app=core&module=developer&controller=acprestrictions&appKey={$this->application->directory}&root=G{$module->key}-{$group}" ) );
}
Output::i()->output = Theme::i()->getTemplate( 'global' )->block( 'acprestrictions_addrow', $form, FALSE );
}
/**
* Delete Restriction Row
*
* @return void
*/
public function restrictionRowDelete() : void
{
/* Make sure the user confirmed the deletion */
Request::i()->confirmedDelete();
$restrictions = $this->_getJson( ROOT_PATH . "/applications/{$this->application->directory}/data/acprestrictions.json" );
$module = $this->_loadModule();
$group = Request::i()->group;
$id = Request::i()->id;
if( isset( $restrictions[ $module->key ][ $group ][ $id ] ) )
{
unset( $restrictions[ $module->key ][ $group ][ $id ] );
$this->_writeJson( ROOT_PATH . "/applications/{$this->application->directory}/data/acprestrictions.json", $restrictions );
}
Output::i()->redirect( Url::internal( "app=core&module=developer&controller=acprestrictions&appKey={$this->application->directory}&root=G{$module->key}-{$group}" ) );
}
}