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
@@ -12,23 +12,34 @@
|
||||
namespace IPS\cms\Theme\Advanced;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DirectoryIterator;
|
||||
use IPS\cms\Theme as SystemTheme;
|
||||
use IPS\Data\Store;
|
||||
use IPS\Db;
|
||||
use IPS\Theme\Dev\Theme as DevTheme;
|
||||
use IPS\Theme\Setup\Theme as SetupTheme;
|
||||
use function count;
|
||||
use function defined;
|
||||
use function strtolower;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Designer's Mode Theme
|
||||
*/
|
||||
class _Theme extends \IPS\cms\Theme
|
||||
class Theme extends SystemTheme
|
||||
{
|
||||
/**
|
||||
* Get currently logged in member's theme
|
||||
*
|
||||
* @return static
|
||||
* @return static|SetupTheme|DevTheme
|
||||
*/
|
||||
public static function i()
|
||||
public static function i() : static|SetupTheme|DevTheme
|
||||
{
|
||||
return new self;
|
||||
}
|
||||
@@ -38,9 +49,9 @@ class _Theme extends \IPS\cms\Theme
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function export()
|
||||
public static function export() : void
|
||||
{
|
||||
foreach( \IPS\Db::i()->select(
|
||||
foreach( Db::i()->select(
|
||||
"*, MD5( CONCAT(template_location, ',', template_group, ',', template_title) ) as bit_key",
|
||||
'cms_templates',
|
||||
NULL,
|
||||
@@ -56,20 +67,20 @@ class _Theme extends \IPS\cms\Theme
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function import()
|
||||
public static function import() : void
|
||||
{
|
||||
$seen = array();
|
||||
|
||||
foreach( array( 'block', 'page', 'database', 'js', 'css' ) as $location )
|
||||
{
|
||||
$templates = iterator_to_array( \IPS\Db::i()->select(
|
||||
$templates = iterator_to_array( Db::i()->select(
|
||||
"*, MD5( CONCAT(template_location, ',', template_group, ',', template_title) ) as bit_key",
|
||||
'cms_templates',
|
||||
array( 'template_location=?', $location ),
|
||||
'template_user_edited ASC' /* Ensure we get edited versions, not the master version if one exists */
|
||||
)->setKeyField('bit_key') );
|
||||
|
||||
$master = iterator_to_array( \IPS\Db::i()->select(
|
||||
$master = iterator_to_array( Db::i()->select(
|
||||
"*, MD5( CONCAT(template_location, ',', template_group, ',', template_title) ) as bit_key",
|
||||
'cms_templates',
|
||||
array( 'template_master=1 and template_location=?', $location )
|
||||
@@ -79,7 +90,7 @@ class _Theme extends \IPS\cms\Theme
|
||||
|
||||
if ( is_dir( $path ) )
|
||||
{
|
||||
foreach( new \DirectoryIterator( $path ) as $group )
|
||||
foreach( new DirectoryIterator( $path ) as $group )
|
||||
{
|
||||
if ( $group->isDot() || mb_substr( $group->getFilename(), 0, 1 ) === '.' )
|
||||
{
|
||||
@@ -90,7 +101,7 @@ class _Theme extends \IPS\cms\Theme
|
||||
{
|
||||
$seen = array();
|
||||
|
||||
foreach( new \DirectoryIterator( $path . '/' . $group->getFilename() ) as $file )
|
||||
foreach( new DirectoryIterator( $path . '/' . $group->getFilename() ) as $file )
|
||||
{
|
||||
if ( $file->isDot() || ( mb_substr( $file->getFilename(), -6 ) !== '.phtml' and mb_substr( $file->getFilename(), -3 ) !== '.js' and mb_substr( $file->getFilename(), -4 ) !== '.css' ) )
|
||||
{
|
||||
@@ -136,7 +147,7 @@ class _Theme extends \IPS\cms\Theme
|
||||
if ( ! $templates[ $key ]['template_master'] )
|
||||
{
|
||||
$added = TRUE;
|
||||
\IPS\Db::i()->update( 'cms_templates', array(
|
||||
Db::i()->update( 'cms_templates', array(
|
||||
'template_content' => $html,
|
||||
'template_params' => ( isset($params[1]) ) ? $params[1] : '',
|
||||
'template_file_object' => NULL
|
||||
@@ -158,7 +169,7 @@ class _Theme extends \IPS\cms\Theme
|
||||
}
|
||||
|
||||
/* New template */
|
||||
\IPS\Db::i()->insert( 'cms_templates', array(
|
||||
Db::i()->insert( 'cms_templates', array(
|
||||
'template_key' => $location . '_' . $group->getFilename() . '_' . $title,
|
||||
'template_title' => $title,
|
||||
'template_desc' => '',
|
||||
@@ -176,19 +187,19 @@ class _Theme extends \IPS\cms\Theme
|
||||
}
|
||||
|
||||
/* remove compiled version */
|
||||
$key = \strtolower( 'template_cms_' .static::makeBuiltTemplateLookupHash( 'cms', $location, $group->getFilename() ) . '_' . static::cleanGroupName( $group->getFilename() ) );
|
||||
$key = strtolower( 'template_cms_' .static::makeBuiltTemplateLookupHash( 'cms', $location, $group->getFilename() ) . '_' . static::cleanGroupName( $group->getFilename() ) );
|
||||
|
||||
if ( isset( \IPS\Data\Store::i()->$key ) )
|
||||
if ( isset( Store::i()->$key ) )
|
||||
{
|
||||
unset(\IPS\Data\Store::i()->$key);
|
||||
unset(Store::i()->$key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove any templates we've not imported for this location/group */
|
||||
if ( \count( $seen ) )
|
||||
if ( count( $seen ) )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'cms_templates', array('template_master=0 and template_location=? and template_group=? and ' . \IPS\Db::i()->in( 'template_title', $seen, TRUE ), $location, $group->getFilename() ) );
|
||||
Db::i()->delete( 'cms_templates', array('template_master=0 and template_location=? and template_group=? and ' . Db::i()->in( 'template_title', $seen, TRUE ), $location, $group->getFilename() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -202,7 +213,7 @@ class _Theme extends \IPS\cms\Theme
|
||||
* @param string|null $path Path or Filename
|
||||
* @return string
|
||||
*/
|
||||
protected static function _getHtmlPath( $app, $location=null, $path=null )
|
||||
protected static function _getHtmlPath( string $app, ?string $location=null, ?string $path=null ) : string
|
||||
{
|
||||
return rtrim( \IPS\ROOT_PATH . "/themes/cms/{$location}/{$path}", '/' ) . '/';
|
||||
}
|
||||
|
||||
@@ -12,31 +12,40 @@
|
||||
namespace IPS\cms\Theme;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use BadMethodCallException;
|
||||
use IPS\cms\Theme;
|
||||
use IPS\Db;
|
||||
use IPS\Theme\Template as ThemeTemplate;
|
||||
use UnderflowException;
|
||||
use function defined;
|
||||
use function function_exists;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic Template Class for IN_DEV mode
|
||||
*/
|
||||
class _Template extends \IPS\Theme\Template
|
||||
class Template extends ThemeTemplate
|
||||
{
|
||||
/**
|
||||
* @brief Source Folder
|
||||
*/
|
||||
public $sourceFolder = NULL;
|
||||
|
||||
public ?string $sourceFolder = NULL;
|
||||
|
||||
/**
|
||||
* Extract the data object from the param tag
|
||||
* @note We always assume the tag is in the format of <ips:template parameters="" data="" />
|
||||
*
|
||||
* @param string $tag <ips:template> tag
|
||||
* @param string $key Data key to fetch
|
||||
* @return null|array
|
||||
* @param string $tag <ips:template> tag
|
||||
* @param string $key Data key to fetch
|
||||
* @return string|null
|
||||
*/
|
||||
public static function extractDataFromTag( $tag, $key="data" )
|
||||
public static function extractDataFromTag( string $tag, string $key="data" ): ?string
|
||||
{
|
||||
if ( ! preg_match( '/^<ips:template parameters="(.+?)?"([^>]+?)>(\r\n?|\n)/', $tag, $matches ) )
|
||||
{
|
||||
@@ -55,10 +64,10 @@ class _Template extends \IPS\Theme\Template
|
||||
* Extract the data object from the param tag
|
||||
* @note We always assume the tag is in the format of <ips:template parameters="" data="" />
|
||||
*
|
||||
* @param string $tag <ips:template> tag
|
||||
* @return null|array
|
||||
* @param string $tag <ips:template> tag
|
||||
* @return null|string
|
||||
*/
|
||||
public static function extractParamsFromTag( $tag )
|
||||
public static function extractParamsFromTag( string $tag ): ?string
|
||||
{
|
||||
if ( ! preg_match( '/^<ips:template parameters="(.+?)?"([^>]+?)>(\r\n?|\n)/', $tag, $matches ) )
|
||||
{
|
||||
@@ -76,18 +85,14 @@ class _Template extends \IPS\Theme\Template
|
||||
* @param string $templateName Template Name
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( $app, $templateLocation, $templateName )
|
||||
public function __construct( string $app, string $templateLocation, string $templateName )
|
||||
{
|
||||
parent::__construct( $app, $templateLocation, $templateName );
|
||||
$this->app = $app;
|
||||
$this->templateLocation = $templateLocation;
|
||||
$this->templateName = $templateName;
|
||||
|
||||
if ( \IPS\Theme::designersModeEnabled() )
|
||||
{
|
||||
$this->sourceFolder = \IPS\ROOT_PATH . "/themes/cms/{$templateLocation}/{$templateName}/";
|
||||
}
|
||||
else if ( \IPS\IN_DEV )
|
||||
if ( \IPS\IN_DEV )
|
||||
{
|
||||
$this->sourceFolder = \IPS\ROOT_PATH . "/applications/{$app}/dev/html/{$templateLocation}/{$templateName}/";
|
||||
}
|
||||
@@ -96,36 +101,35 @@ class _Template extends \IPS\Theme\Template
|
||||
/**
|
||||
* Magic Method: Call Template Bit
|
||||
*
|
||||
* @param string $bit Template Bit Name
|
||||
* @param array $params Parameters
|
||||
* @return string
|
||||
* @param string $bit Template Bit Name
|
||||
* @param array $params Parameters
|
||||
*/
|
||||
public function __call( $bit, $params )
|
||||
public function __call( string $bit, array $params )
|
||||
{
|
||||
if ( \IPS\IN_DEV or \IPS\Theme::designersModeEnabled() )
|
||||
if ( \IPS\IN_DEV )
|
||||
{
|
||||
/* What are we calling this? */
|
||||
$functionName = "theme_{$this->app}_{$this->templateLocation}_{$this->templateName}_{$bit}";
|
||||
|
||||
/* If it doesn't exist, build it */
|
||||
if( !\function_exists( 'IPS\\Theme\\'.$functionName ) )
|
||||
if( !function_exists( 'IPS\\Theme\\'.$functionName ) )
|
||||
{
|
||||
/* Find the file */
|
||||
$file = $this->sourceFolder . $bit . '.phtml';
|
||||
|
||||
/* Get the content */
|
||||
if ( $file === NULL or !file_exists( $file ) )
|
||||
if ( !file_exists( $file ) )
|
||||
{
|
||||
/* Try the database */
|
||||
try
|
||||
{
|
||||
$template = \IPS\Db::i()->select( '*', 'cms_templates', array( 'template_location=? and LOWER(template_group)=? and template_title=?', $this->templateLocation, $this->templateName, $bit ) )->first();
|
||||
$template = Db::i()->select( '*', 'cms_templates', array( 'template_location=? and LOWER(template_group)=? and template_title=?', $this->templateLocation, $this->templateName, $bit ) )->first();
|
||||
|
||||
\IPS\cms\Theme::makeProcessFunction( $template['template_content'], $functionName, $template['template_params'], TRUE );
|
||||
Theme::makeProcessFunction( $template['template_content'], $functionName, $template['template_params'], TRUE );
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
catch ( UnderflowException $e )
|
||||
{
|
||||
throw new \BadMethodCallException( 'NO_TEMPLATE_FILE - ' . $file );
|
||||
throw new BadMethodCallException( 'NO_TEMPLATE_FILE - ' . $file );
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -136,14 +140,14 @@ class _Template extends \IPS\Theme\Template
|
||||
/* Parse the header tag */
|
||||
if ( !preg_match( '/^<ips:template parameters="(.+?)?"([^>]+?)>(\r\n?|\n)/', $output, $matches ) )
|
||||
{
|
||||
throw new \BadMethodCallException( 'NO_HEADER - ' . $file );
|
||||
throw new BadMethodCallException( 'NO_HEADER - ' . $file );
|
||||
}
|
||||
|
||||
/* Strip it */
|
||||
$output = preg_replace( '/^<ips:template parameters="(.+?)?"([^>]+?)>(\r\n?|\n)/', '', $output );
|
||||
|
||||
/* Make it into a lovely function */
|
||||
\IPS\cms\Theme::makeProcessFunction( $output, $functionName, ( isset( $matches[1] ) ? $matches[1] : '' ), TRUE );
|
||||
Theme::makeProcessFunction( $output, $functionName, ( $matches[1] ?? '' ), TRUE );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,29 +12,59 @@
|
||||
namespace IPS\cms;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DirectoryIterator;
|
||||
use DomainException;
|
||||
use ErrorException;
|
||||
use IPS\Data\Store;
|
||||
use IPS\Db;
|
||||
use IPS\Dispatcher;
|
||||
use IPS\Http\Url\Friendly;
|
||||
use IPS\Log;
|
||||
use IPS\Login;
|
||||
use IPS\Member;
|
||||
use IPS\Theme as SystemTheme;
|
||||
use IPS\Theme\Dev\Template;
|
||||
use IPS\Theme\Dev\Theme as DevTheme;
|
||||
use IPS\Theme\Setup\Theme as SetupTheme;
|
||||
use ParseError;
|
||||
use RuntimeException;
|
||||
use UnexpectedValueException;
|
||||
use function count;
|
||||
use function defined;
|
||||
use function file_put_contents;
|
||||
use function in_array;
|
||||
use function is_array;
|
||||
use function is_string;
|
||||
use function strtolower;
|
||||
use const IPS\IPS_FILE_PERMISSION;
|
||||
use const IPS\IPS_FOLDER_PERMISSION;
|
||||
use const IPS\IN_DEV;
|
||||
use const IPS\ROOT_PATH;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* IN_DEV Skin set
|
||||
*/
|
||||
class _Theme extends \IPS\Theme
|
||||
class Theme extends SystemTheme
|
||||
{
|
||||
/**
|
||||
* @brief Template Classes
|
||||
*/
|
||||
protected $templates;
|
||||
protected ?array $templates = null;
|
||||
|
||||
/**
|
||||
* @brief [SkinSets] Templates already loaded and evald via getTemplate()
|
||||
*/
|
||||
public static $calledTemplates = array();
|
||||
public static array $calledTemplates = array();
|
||||
|
||||
/**
|
||||
* @brief Return type for getRawTemplates/getRawCss: Uses DB if not IN_DEV, otherwise uses disk .phtml look up
|
||||
* @brief Return type for getAllTemplates/getRawCss: Uses DB if not IN_DEV, otherwise uses disk .phtml look up
|
||||
*/
|
||||
const RETURN_AS_OBJECT = 32;
|
||||
|
||||
@@ -69,71 +99,43 @@ class _Theme extends \IPS\Theme
|
||||
const RETURN_BLOCK = 2048;
|
||||
|
||||
/**
|
||||
* @brief Return just contents of cms_templates ignoring IN_DEV and DESIGNERS' MODE
|
||||
* @brief Return just contents of cms_templates ignoring IN_DEV
|
||||
*/
|
||||
const RETURN_DATABASE_ONLY = 4096;
|
||||
|
||||
/**
|
||||
* Get currently logged in member's theme
|
||||
*
|
||||
* @return \IPS\Theme
|
||||
* @return static|DevTheme|SystemTheme
|
||||
*/
|
||||
public static function i()
|
||||
public static function i(): static|SetupTheme|DevTheme
|
||||
{
|
||||
if ( \IPS\Theme::designersModeEnabled() )
|
||||
{
|
||||
return new \IPS\cms\Theme\Advanced\Theme;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new self;
|
||||
}
|
||||
return new self;
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports templates from the /dev directories.
|
||||
*
|
||||
* @param string $location Location (database, block)
|
||||
* @param string $location Location (database, block)
|
||||
* @return void
|
||||
*/
|
||||
public static function importInDev( $location )
|
||||
public static function importFromFiles( string $location ): void
|
||||
{
|
||||
/* Clear out existing template bits */
|
||||
\IPS\Db::i()->delete( 'cms_templates', array( 'template_master=1 and template_user_created=0 and template_user_edited=0 AND template_location=?', $location ) );
|
||||
Db::i()->delete( 'cms_templates', array( 'template_master=1 and template_user_created=0 and template_user_edited=0 AND template_location=?', $location ) );
|
||||
|
||||
static::importLocation( $location );
|
||||
}
|
||||
|
||||
/**
|
||||
* Write IN_DEV files
|
||||
*
|
||||
* @param boolean $force TRUE to rewrite templates, FALSE to check if exists first
|
||||
* @return void
|
||||
*/
|
||||
public static function writeInDev( $force=FALSE )
|
||||
{
|
||||
foreach( \IPS\Db::i()->select( '*', 'cms_templates', array( 'template_master=?', 1 ) ) as $template )
|
||||
{
|
||||
try
|
||||
{
|
||||
static::writeTemplate( $template, $force );
|
||||
}
|
||||
catch( \RuntimeException $ex )
|
||||
{
|
||||
throw new \RuntimeException( $ex->getMessage() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports templates from the /dev directories.
|
||||
*
|
||||
* @param string $location Location (database, block)
|
||||
* @param string $location Location (database, block)
|
||||
* @return array
|
||||
*/
|
||||
public static function importLocation( $location )
|
||||
public static function importLocation( string $location ): array
|
||||
{
|
||||
$master = iterator_to_array( \IPS\Db::i()->select(
|
||||
$master = iterator_to_array( Db::i()->select(
|
||||
"*, MD5( CONCAT(template_location, ',', template_group, ',', template_title) ) as bit_key",
|
||||
'cms_templates',
|
||||
array( 'template_master=1 and template_user_created=0 and template_user_edited=0 AND template_location=?', $location )
|
||||
@@ -144,7 +146,7 @@ class _Theme extends \IPS\Theme
|
||||
|
||||
if ( is_dir( $path ) )
|
||||
{
|
||||
foreach( new \DirectoryIterator( $path ) as $group )
|
||||
foreach( new DirectoryIterator( $path ) as $group )
|
||||
{
|
||||
if ( $group->isDot() || mb_substr( $group->getFilename(), 0, 1 ) === '.' || $group->getFilename() == 'index.html' )
|
||||
{
|
||||
@@ -153,7 +155,7 @@ class _Theme extends \IPS\Theme
|
||||
|
||||
if ( $group->isDir() )
|
||||
{
|
||||
foreach( new \DirectoryIterator( $path . '/' . $group->getFilename() ) as $file )
|
||||
foreach( new DirectoryIterator( $path . '/' . $group->getFilename() ) as $file )
|
||||
{
|
||||
if ( $file->isDot() || mb_substr( $file->getFilename(), -6 ) !== '.phtml')
|
||||
{
|
||||
@@ -175,7 +177,7 @@ class _Theme extends \IPS\Theme
|
||||
|
||||
if ( isset( $master[ $key ] ) )
|
||||
{
|
||||
if( \IPS\Login::compareHashes( md5( trim( $master[ $key ]['template_content'] ) ), md5( trim( $html ) ) ) )
|
||||
if( Login::compareHashes( md5( trim( $master[ $key ]['template_content'] ) ), md5( trim( $html ) ) ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -184,14 +186,14 @@ class _Theme extends \IPS\Theme
|
||||
$seen[ $group->getFilename() ] = $title;
|
||||
|
||||
/* remove compiled version */
|
||||
$key = \strtolower( 'template_cms_' .static::makeBuiltTemplateLookupHash( 'cms', $location, $group->getFilename() ) . '_' . static::cleanGroupName( $group->getFilename() ) );
|
||||
$key = strtolower( 'template_cms_' .static::makeBuiltTemplateLookupHash( 'cms', $location, $group->getFilename() ) . '_' . static::cleanGroupName( $group->getFilename() ) );
|
||||
|
||||
if ( isset( \IPS\Data\Store::i()->$key ) )
|
||||
if ( isset( Store::i()->$key ) )
|
||||
{
|
||||
unset(\IPS\Data\Store::i()->$key);
|
||||
unset(Store::i()->$key);
|
||||
}
|
||||
|
||||
\IPS\Db::i()->insert( 'cms_templates', array(
|
||||
Db::i()->insert( 'cms_templates', array(
|
||||
'template_key' => $location . '_' . $group->getFilename() . '_' . $title,
|
||||
'template_title' => $title,
|
||||
'template_desc' => '',
|
||||
@@ -217,30 +219,30 @@ class _Theme extends \IPS\Theme
|
||||
* @param array $template Template to write
|
||||
* @param boolean $force Force overwrite
|
||||
* @return void
|
||||
* @throws \RuntimeException
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public static function writeTemplate( $template, $force=FALSE )
|
||||
public static function writeTemplate( array $template, bool $force=FALSE ) : void
|
||||
{
|
||||
$path = static::_getHtmlPath('cms');
|
||||
|
||||
if ( ! is_dir( $path ) )
|
||||
{
|
||||
if ( ! mkdir( $path, \IPS\IPS_FOLDER_PERMISSION, TRUE ) )
|
||||
if ( ! mkdir( $path, IPS_FOLDER_PERMISSION, TRUE ) )
|
||||
{
|
||||
throw new \DomainException();
|
||||
throw new DomainException();
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! is_dir( $path . '/' . $template['template_location'] ) )
|
||||
{
|
||||
mkdir( $path . '/' . $template['template_location'] );
|
||||
@chmod( $path . '/' . $template['template_location'], \IPS\IPS_FOLDER_PERMISSION );
|
||||
@chmod( $path . '/' . $template['template_location'], IPS_FOLDER_PERMISSION );
|
||||
}
|
||||
|
||||
if ( ! is_dir( $path . '/' . $template['template_location'] . '/' . $template['template_group'] ) )
|
||||
{
|
||||
mkdir( $path . '/' . $template['template_location'] . '/' . $template['template_group'] );
|
||||
@chmod( $path . '/' . $template['template_location'] . '/' . $template['template_group'], \IPS\IPS_FOLDER_PERMISSION );
|
||||
@chmod( $path . '/' . $template['template_location'] . '/' . $template['template_group'], IPS_FOLDER_PERMISSION );
|
||||
}
|
||||
|
||||
$fileName = ( $template['template_type'] === 'template' ) ? $template['template_title'] . '.phtml' : $template['template_title'];
|
||||
@@ -256,13 +258,13 @@ class _Theme extends \IPS\Theme
|
||||
|
||||
$write .= $template['template_content'];
|
||||
|
||||
if ( @\file_put_contents( $path . '/' . $template['template_location'] . '/' . $template['template_group'] . '/' . $fileName, $write ) === FALSE )
|
||||
if ( @file_put_contents( $path . '/' . $template['template_location'] . '/' . $template['template_group'] . '/' . $fileName, $write ) === FALSE )
|
||||
{
|
||||
throw new \RuntimeException( \IPS\Member::loggedIn()->language()->addToStack( 'content_theme_dev_cannot_write_template', FALSE, array( 'sprintf' => array( $path . '/' . $template['template_location'] . '/' . $template['template_group'] . '/' . $fileName ) ) ) );
|
||||
throw new RuntimeException( Member::loggedIn()->language()->addToStack( 'content_theme_dev_cannot_write_template', FALSE, array( 'sprintf' => array( $path . '/' . $template['template_location'] . '/' . $template['template_group'] . '/' . $fileName ) ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
@chmod( $path . '/' . $template['template_location'] . '/' . $template['template_group'] . '/' . $fileName, \IPS\IPS_FILE_PERMISSION );
|
||||
@chmod( $path . '/' . $template['template_location'] . '/' . $template['template_group'] . '/' . $fileName, IPS_FILE_PERMISSION );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -270,31 +272,31 @@ class _Theme extends \IPS\Theme
|
||||
/**
|
||||
* Get raw templates. Raw means HTML logic and variables are still in {{format}}
|
||||
*
|
||||
* @param string|array $app Template app (e.g. core, forum)
|
||||
* @param string|array $location Template location (e.g. admin,global,front)
|
||||
* @param string|array $group Template group (e.g. login, share)
|
||||
* @param int|constant $returnType Determines the content returned
|
||||
* @param boolean $returnThisSetOnly Returns rows unique to this set only
|
||||
* @param array|string $app Template app (e.g. core, forum)
|
||||
* @param array|string $location Template location (e.g. admin,global,front)
|
||||
* @param array|string $group Template group (e.g. login, share)
|
||||
* @param int|null $returnType Determines the content returned
|
||||
* @param boolean $returnThisSetOnly Returns rows unique to this set only
|
||||
* @return array
|
||||
*/
|
||||
public function getRawTemplates( $app=array(), $location=array(), $group=array(), $returnType=null, $returnThisSetOnly=false )
|
||||
public function getAllTemplates( array|string $app=array(), array|string $location=array(), array|string $group=array(), int $returnType=null, bool $returnThisSetOnly=false ): array
|
||||
{
|
||||
$returnType = ( $returnType === null ) ? self::RETURN_ALL : $returnType;
|
||||
$app = ( \is_string( $app ) AND ! empty( $app ) ) ? array( $app ) : $app;
|
||||
$location = ( \is_string( $location ) AND ! empty( $location ) ) ? array( $location ) : $location;
|
||||
$group = ( \is_string( $group ) AND ! empty( $group ) ) ? array( $group ) : $group;
|
||||
$app = ( is_string( $app ) AND ! empty( $app ) ) ? array( $app ) : $app;
|
||||
$location = ( is_string( $location ) AND ! empty( $location ) ) ? array( $location ) : $location;
|
||||
$group = ( is_string( $group ) AND ! empty( $group ) ) ? array( $group ) : $group;
|
||||
$where = array();
|
||||
$templates = array();
|
||||
|
||||
if ( ( \IPS\IN_DEV or \IPS\Theme::designersModeEnabled() ) AND ! ( $returnType & static::RETURN_DATABASE_ONLY ) )
|
||||
if ( ( IN_DEV ) AND ! ( $returnType & static::RETURN_DATABASE_ONLY ) )
|
||||
{
|
||||
$fixedLocations = array( 'admin', 'front', 'global' );
|
||||
$results = array();
|
||||
$seenKeys = array();
|
||||
|
||||
foreach( new \DirectoryIterator( static::_getHtmlPath('cms') ) as $location )
|
||||
foreach( new DirectoryIterator( static::_getHtmlPath('cms') ) as $location )
|
||||
{
|
||||
if ( ! \in_array( $location->getFilename(), $fixedLocations ) AND $location->isDir() AND mb_substr( $location->getFilename(), 0, 1 ) !== '.' )
|
||||
if ( ! in_array( $location->getFilename(), $fixedLocations ) AND $location->isDir() AND mb_substr( $location->getFilename(), 0, 1 ) !== '.' )
|
||||
{
|
||||
$allowedLocations = array();
|
||||
if ( $returnType & static::RETURN_ONLY_TEMPLATE )
|
||||
@@ -329,31 +331,31 @@ class _Theme extends \IPS\Theme
|
||||
}
|
||||
}
|
||||
|
||||
if ( \count( $allowedLocations ) and ! \in_array( $location->getFilename(), $allowedLocations ) )
|
||||
if ( count( $allowedLocations ) and ! in_array( $location->getFilename(), $allowedLocations ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach( new \DirectoryIterator( static::_getHtmlPath( 'cms', $location->getFilename() ) ) as $file )
|
||||
foreach( new DirectoryIterator( static::_getHtmlPath( 'cms', $location->getFilename() ) ) as $file )
|
||||
{
|
||||
if ( $file->isDir() AND mb_substr( $file->getFilename(), 0, 1 ) !== '.' )
|
||||
{
|
||||
if ( $group === NULL or ! \count( $group ) or ( \in_array( $file->getFilename(), $group ) ) )
|
||||
if ( empty( $group ) or ! count( $group ) or ( in_array( $file->getFilename(), $group ) ) )
|
||||
{
|
||||
foreach( new \DirectoryIterator( static::_getHtmlPath( 'cms', $location->getFilename(), $file->getFilename() ) ) as $template )
|
||||
foreach( new DirectoryIterator( static::_getHtmlPath( 'cms', $location->getFilename(), $file->getFilename() ) ) as $template )
|
||||
{
|
||||
if ( ! $template->isDir() AND ( mb_substr( $template->getFilename(), -6 ) === '.phtml' or mb_substr( $template->getFilename(), -4 ) === '.css' or mb_substr( $template->getFilename(), -3 ) === '.js' ) )
|
||||
{
|
||||
$title = str_replace( ".phtml", "", $template->getFilename() );
|
||||
|
||||
$contents = file_get_contents( static::_getHtmlPath( 'cms', $location->getFilename(), $file->getFilename() ) . '/' . $template->getFilename() );
|
||||
$key = \IPS\cms\Theme\Template::extractDataFromTag( $contents, 'key' );
|
||||
$key = $key ? $key : \IPS\Http\Url\Friendly::seoTitle( $file->getFilename() . '_' . $title );
|
||||
$ogroup = \IPS\cms\Theme\Template::extractDataFromTag( $contents, 'original_group' );
|
||||
$params = \IPS\cms\Theme\Template::extractParamsFromTag( $contents );
|
||||
$key = Theme\Template::extractDataFromTag( $contents, 'key' );
|
||||
$key = $key ?: Friendly::seoTitle( $file->getFilename() . '_' . $title );
|
||||
$ogroup = Theme\Template::extractDataFromTag( $contents, 'original_group' );
|
||||
$params = Theme\Template::extractParamsFromTag( $contents );
|
||||
$container = NULL;
|
||||
|
||||
if ( \in_array( $key, $seenKeys ) )
|
||||
if ( in_array( $key, $seenKeys ) )
|
||||
{
|
||||
$key .= filemtime( static::_getHtmlPath( 'cms', $location->getFilename(), $file->getFilename() ) . '/' . $template->getFilename() ) . mt_rand();
|
||||
}
|
||||
@@ -364,7 +366,7 @@ class _Theme extends \IPS\Theme
|
||||
|
||||
if ( $returnType & static::RETURN_AS_OBJECT )
|
||||
{
|
||||
$object = new \IPS\cms\Templates;
|
||||
$object = new Templates;
|
||||
$object->key = $key;
|
||||
$object->title = $title;
|
||||
$object->desc = NULL;
|
||||
@@ -372,7 +374,7 @@ class _Theme extends \IPS\Theme
|
||||
$object->content = $contents;
|
||||
$object->location = $location->getFilename();
|
||||
$object->group = $file->getFilename();
|
||||
$object->original_group = isset( $ogroup ) ? $ogroup : $object->group;
|
||||
$object->original_group = $ogroup ?? $object->group;
|
||||
$object->user_created = 0;
|
||||
$object->user_edited = 0;
|
||||
$object->params = $params;
|
||||
@@ -389,7 +391,7 @@ class _Theme extends \IPS\Theme
|
||||
'template_content' => $contents,
|
||||
'template_location' => $location->getFilename(),
|
||||
'template_group' => $file->getFilename(),
|
||||
'template_original_group' => isset( $ogroup ) ? $ogroup : $file->getFilename(),
|
||||
'template_original_group' => $ogroup ?? $file->getFilename(),
|
||||
'template_user_created' => 0,
|
||||
'template_user_edited' => 0,
|
||||
'template_params' => $params,
|
||||
@@ -416,12 +418,12 @@ class _Theme extends \IPS\Theme
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( \is_array( $location ) AND \count( $location ) )
|
||||
if ( is_array( $location ) AND count( $location ) )
|
||||
{
|
||||
$where[] = "template_location IN ('" . implode( "','", $location ) . "')";
|
||||
}
|
||||
|
||||
if ( \is_array( $group ) AND \count( $group ) )
|
||||
if ( is_array( $group ) AND count( $group ) )
|
||||
{
|
||||
$where[] = "template_group IN ('" . implode( "','", $group ) . "')";
|
||||
}
|
||||
@@ -443,7 +445,7 @@ class _Theme extends \IPS\Theme
|
||||
$originalTemplateNames = array();
|
||||
$groupMap = array();
|
||||
|
||||
foreach( \IPS\Db::i()->select( '*', 'cms_templates', implode( " AND ", $where ), 'template_location, template_group, template_key, template_user_edited ASC' ) as $row )
|
||||
foreach( Db::i()->select( '*', 'cms_templates', implode( " AND ", $where ), 'template_location, template_group, template_key, template_user_edited ASC' ) as $row )
|
||||
{
|
||||
$rawTemplates[] = $row;
|
||||
$templateNames[ $row['template_original_group'] ][] = $row['template_title'];
|
||||
@@ -455,9 +457,9 @@ class _Theme extends \IPS\Theme
|
||||
}
|
||||
}
|
||||
|
||||
if ( \count( $originalGroups ) )
|
||||
if ( count( $originalGroups ) )
|
||||
{
|
||||
foreach( \IPS\Db::i()->select( '*', 'cms_templates', array( array( 'template_original_group = template_group '), array( \IPS\Db::i()->in( 'template_original_group', $originalGroups ) ) ) ) as $row )
|
||||
foreach( Db::i()->select( '*', 'cms_templates', array( array( 'template_original_group = template_group '), array( Db::i()->in( 'template_original_group', $originalGroups ) ) ) ) as $row )
|
||||
{
|
||||
$originalTemplates[ $row['template_group'] . '_' . $row['template_title'] ] = $row;
|
||||
$originalTemplateNames[ $row['template_group'] ][] = $row['template_title'];
|
||||
@@ -471,7 +473,7 @@ class _Theme extends \IPS\Theme
|
||||
{
|
||||
foreach( $names as $name )
|
||||
{
|
||||
if ( ! \in_array( $name, $templateNames[ $group ] ) )
|
||||
if ( ! in_array( $name, $templateNames[ $group ] ) )
|
||||
{
|
||||
$rawTemplates[] = array_merge( $originalTemplates[ $group . '_' . $name ], array( 'template_group' => $groupMap[ $group ]) );
|
||||
}
|
||||
@@ -538,37 +540,37 @@ class _Theme extends \IPS\Theme
|
||||
/**
|
||||
* Get a template
|
||||
*
|
||||
* @param string $group Template Group
|
||||
* @param string $app Application key (NULL for current application)
|
||||
* @param string $location Template Location (NULL for current template location)
|
||||
* @return \IPS\Theme\Template
|
||||
* @param string $group Template Group
|
||||
* @param string|null $app Application key (NULL for current application)
|
||||
* @param string|null $location Template Location (NULL for current template location)
|
||||
* @return mixed
|
||||
*/
|
||||
public function getTemplate( $group, $app=NULL, $location=NULL )
|
||||
public function getTemplate( string $group, string $app=NULL, string $location=NULL ): mixed
|
||||
{
|
||||
/* Do we have an application? */
|
||||
if( $app === NULL )
|
||||
{
|
||||
$app = \IPS\Dispatcher::i()->application->directory;
|
||||
$app = Dispatcher::i()->application->directory;
|
||||
}
|
||||
|
||||
/* How about a template location? */
|
||||
if( $location === NULL )
|
||||
{
|
||||
$location = \IPS\Dispatcher::i()->controllerLocation;
|
||||
$location = Dispatcher::i()->controllerLocation;
|
||||
}
|
||||
|
||||
/* Get template */
|
||||
if ( \IPS\IN_DEV or \IPS\Theme::designersModeEnabled() )
|
||||
if ( IN_DEV )
|
||||
{
|
||||
if ( ! isset( $this->templates[ $app ][ $location ][ $group ] ) )
|
||||
{
|
||||
if ( $app === 'cms' AND ! \in_array( $location, array( 'admin', 'front', 'global' ) ) )
|
||||
if ( $app === 'cms' AND ! in_array( $location, array( 'admin', 'front', 'global' ) ) )
|
||||
{
|
||||
$this->templates[ $app ][ $location ][ $group ] = new \IPS\cms\Theme\Template( $app, $location, $group );
|
||||
$this->templates[ $app ][ $location ][ $group ] = new Template( $app, $location, $group );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->templates[ $app ][ $location ][ $group ] = \IPS\Theme::i()->getTemplate( $group, $app, $location );
|
||||
$this->templates[ $app ][ $location ][ $group ] = Theme::i()->getTemplate( $group, $app, $location );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -579,42 +581,42 @@ class _Theme extends \IPS\Theme
|
||||
/* Group is saved clean */
|
||||
$group = static::cleanGroupName( $group );
|
||||
|
||||
if ( ( $app !== 'cms' ) OR ( $app === 'cms' AND \in_array( $location, array( 'admin', 'front', 'global' ) ) ) )
|
||||
if ( ( $app !== 'cms' ) OR ( in_array( $location, array( 'admin', 'front', 'global' ) ) ) )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( $group, $app, $location );
|
||||
return SystemTheme::i()->getTemplate( $group, $app, $location );
|
||||
}
|
||||
|
||||
$key = \strtolower( 'template_cms_' .static::makeBuiltTemplateLookupHash( $app, $location, $group ) . '_' . static::cleanGroupName( $group ) );
|
||||
$key = strtolower( 'template_cms_' .static::makeBuiltTemplateLookupHash( $app, $location, $group ) . '_' . static::cleanGroupName( $group ) );
|
||||
|
||||
/* Still here */
|
||||
if ( !\in_array( $key, array_keys( static::$calledTemplates ) ) )
|
||||
if ( !in_array( $key, array_keys( static::$calledTemplates ) ) )
|
||||
{
|
||||
/* If we don't have a compiled template, do that now */
|
||||
if ( !isset( \IPS\Data\Store::i()->$key ) )
|
||||
if ( !isset( Store::i()->$key ) )
|
||||
{
|
||||
$this->compileTemplates( $app, $location, $group );
|
||||
}
|
||||
|
||||
/* Still no key? */
|
||||
if ( ! isset( \IPS\Data\Store::i()->$key ) )
|
||||
if ( ! isset( Store::i()->$key ) )
|
||||
{
|
||||
\IPS\Log::log( "Template store key: {$key} missing ({$app}, {$location}, {$group})", "template_store_missing" );
|
||||
Log::log( "Template store key: {$key} missing ({$app}, {$location}, {$group})", "template_store_missing" );
|
||||
|
||||
throw new \ErrorException('template_store_missing ' . $key);
|
||||
throw new ErrorException('template_store_missing ' . $key);
|
||||
}
|
||||
|
||||
/* Load compiled template */
|
||||
$compiledGroup = \IPS\Data\Store::i()->$key;
|
||||
$compiledGroup = Store::i()->$key;
|
||||
try
|
||||
{
|
||||
if ( @eval( $compiledGroup ) === FALSE )
|
||||
{
|
||||
throw new \UnexpectedValueException;
|
||||
throw new UnexpectedValueException;
|
||||
}
|
||||
}
|
||||
catch ( \ParseError $e )
|
||||
catch ( ParseError $e )
|
||||
{
|
||||
throw new \UnexpectedValueException;
|
||||
throw new UnexpectedValueException;
|
||||
}
|
||||
|
||||
/* Hooks */
|
||||
@@ -633,14 +635,14 @@ class _Theme extends \IPS\Theme
|
||||
* Build Templates ready for non IN_DEV use
|
||||
* This fetches all templates in a group, converts HTML logic into ready to eval PHP and stores as a single PHP class per template group
|
||||
*
|
||||
* @param string|array $app Templates app (e.g. core, forum)
|
||||
* @param string|array $location Templates location (e.g. admin,global,front)
|
||||
* @param string|array $group Templates group (e.g. forms, members)
|
||||
* @return void
|
||||
* @param array|string|null $app Templates app (e.g. core, forum)
|
||||
* @param array|string|null $location Templates location (e.g. admin,global,front)
|
||||
* @param array|string|null $group Templates group (e.g. forms, members)
|
||||
* @return bool
|
||||
*/
|
||||
public function compileTemplates( $app=null, $location=null, $group=null )
|
||||
public function compileTemplates( array|string $app=null, array|string $location=null, array|string $group=null ): bool
|
||||
{
|
||||
$templates = $this->getRawTemplates( $app, $location, static::cleanGroupName( $group ) );
|
||||
$templates = $this->getAllTemplates( $app, $location, static::cleanGroupName( $group ) );
|
||||
|
||||
foreach( $templates as $templateApp => $v )
|
||||
{
|
||||
@@ -648,37 +650,10 @@ class _Theme extends \IPS\Theme
|
||||
{
|
||||
foreach( $templates[ $templateApp ][ $location ] as $group => $bits )
|
||||
{
|
||||
|
||||
/* Any template hooks? */
|
||||
$templateHooks = array();
|
||||
if( isset( \IPS\IPS::$hooks[ "\IPS\Theme\class_{$app}_{$location}_{$group}" ] ) AND \IPS\RECOVERY_MODE === FALSE )
|
||||
{
|
||||
foreach ( \IPS\IPS::$hooks[ "\IPS\Theme\class_{$app}_{$location}_{$group}" ] as $k => $data )
|
||||
{
|
||||
if ( !class_exists( "IPS\Theme\hook{$k}", FALSE ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
if ( @eval( "namespace IPS\Theme;\n\n" . str_replace( ' extends _HOOK_CLASS_', '', file_get_contents( \IPS\ROOT_PATH . '/' . $data['file'] ) ) ) !== FALSE )
|
||||
{
|
||||
$class = "IPS\Theme\hook{$data['class']}";
|
||||
$templateHooks = array_merge( $templateHooks, $class::hookData() );
|
||||
}
|
||||
}
|
||||
catch ( \ParseError $e ) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Build all the functions */
|
||||
$functions = array();
|
||||
foreach( $templates[ $templateApp ][ $location ][ $group ] as $name => $data )
|
||||
{
|
||||
if ( isset( $templateHooks[ $name ] ) )
|
||||
{
|
||||
$data['template_content'] = static::themeHooks( $data['template_content'], $templateHooks[ $name ] );
|
||||
}
|
||||
|
||||
$functions[ $name ] = static::compileTemplate( $data['template_content'], $data['template_title'], $data['template_params'], true, false, $app, $location, $group );
|
||||
}
|
||||
|
||||
@@ -696,27 +671,29 @@ EOF;
|
||||
EOF;
|
||||
|
||||
/* Store it */
|
||||
$key = \strtolower( 'template_cms_' . static::makeBuiltTemplateLookupHash( $app, $location, $group ) . '_' . static::cleanGroupName( $group ) );
|
||||
$key = strtolower( 'template_cms_' . static::makeBuiltTemplateLookupHash( $app, $location, $group ) . '_' . static::cleanGroupName( $group ) );
|
||||
|
||||
\IPS\Data\Store::i()->$key = $template;
|
||||
Store::i()->$key = $template;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete compiled templates
|
||||
* Removes compiled templates bits for all themes that match the arguments
|
||||
*
|
||||
* @param string $app Application Directory (core, forums, etc)
|
||||
* @param string|null $location Template location (front, admin, global, etc)
|
||||
* @param string|null $group Template group (forms, messaging, etc)
|
||||
* @param int|null $themeId Limit to a specific theme (and children)
|
||||
* @param string|null $app Application Directory (core, forums, etc)
|
||||
* @param array|string|null $location Template location (front, admin, global, etc)
|
||||
* @param array|string|null $group Template group (forms, messaging, etc)
|
||||
* @param int|null $themeId Limit to a specific theme (and children)
|
||||
* @return void
|
||||
*/
|
||||
public static function deleteCompiledTemplate( $app=null, $location=null, $group=null, $themeId=null )
|
||||
public static function deleteCompiledTemplate( string $app=null, array|string|null $location=null, array|string|null $group=null, int $themeId=null ): void
|
||||
{
|
||||
$templates = \IPS\cms\Theme::i()->getRawTemplates( $app, $location, $group );
|
||||
$templates = Theme::i()->getAllTemplates( $app, $location, $group );
|
||||
|
||||
foreach( $templates as $templateApp => $v )
|
||||
{
|
||||
@@ -724,11 +701,11 @@ EOF;
|
||||
{
|
||||
foreach( $templates[ $templateApp ][ $location ] as $group => $bits )
|
||||
{
|
||||
$key = \strtolower( 'template_cms_' . static::makeBuiltTemplateLookupHash( $app, $location, $group ) . '_' . static::cleanGroupName( $group ) );
|
||||
$key = strtolower( 'template_cms_' . static::makeBuiltTemplateLookupHash( $app, $location, $group ) . '_' . static::cleanGroupName( $group ) );
|
||||
|
||||
if ( isset( \IPS\Data\Store::i()->$key ) )
|
||||
if ( isset( Store::i()->$key ) )
|
||||
{
|
||||
unset( \IPS\Data\Store::i()->$key );
|
||||
unset( Store::i()->$key );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -744,9 +721,9 @@ EOF;
|
||||
* @param string|null $path Path or Filename
|
||||
* @return string
|
||||
*/
|
||||
protected static function _getHtmlPath( $app, $location=null, $path=null )
|
||||
protected static function _getHtmlPath( string $app, ?string $location=null, ?string $path=null ) : string
|
||||
{
|
||||
return rtrim( \IPS\ROOT_PATH . "/applications/{$app}/dev/html/{$location}/{$path}", '/' ) . '/';
|
||||
return rtrim( ROOT_PATH . "/applications/{$app}/dev/html/{$location}/{$path}", '/' ) . '/';
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user