Version 4.5.0

This commit is contained in:
Neo committed 2025-12-19 05:51:58 -08:00
1 parent 1a0c7fd3c2
commit f79dcf067a
3791 files changed
+248032 -76372

No files matched your search

+106 -30
View File
@@ -11,7 +11,7 @@
namespace IPS;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -36,6 +36,11 @@ class _Plugin extends \IPS\Node\Model
* @brief [ActiveRecord] Database Prefix
*/
public static $databasePrefix = 'plugin_';
/**
* @brief [ActiveRecord] Database ID Fields
*/
protected static $databaseIdFields = array( 'plugin_id', 'plugin_marketplace_id' );
/**
* @brief [Node] Order Database Column
@@ -83,7 +88,37 @@ class _Plugin extends \IPS\Node\Model
'delete' => 'plugins_uninstall'
),
);
/**
* @brief [ActiveRecord] Caches
* @note Defined cache keys will be cleared automatically as needed
*/
protected $caches = array( 'updatecount_plugins' );
/**
* [Node] Get Node Description
*
* @return string|null
*/
protected function get__description()
{
return \IPS\Theme::i()->getTemplate( 'plugins', 'core' )->pluginRowDescription( $this );
}
/**
* Get the authors website
*
* @return \IPS\Http\Url|null
*/
public function website()
{
if ( $this->_data['website'] )
{
return \IPS\Http\Url::createFromString( $this->_data['website'] );
}
return NULL;
}
/**
* Get Plugins
*
@@ -215,8 +250,8 @@ class _Plugin extends \IPS\Node\Model
public function form( &$form )
{
$form->addHeader( 'plugin_details' );
$form->add( new \IPS\Helpers\Form\Text( 'plugin_name', $this->name, TRUE, array( 'maxLength' => 32 ) ) );
$form->add( new \IPS\Helpers\Form\Text( 'plugin_location', $this->location, FALSE, array( 'disabled' => $this->_id ? TRUE : FALSE, 'maxLength' => 32, 'regex' => '/^[a-z][a-z0-9]*$/i' ) ) );
$form->add( new \IPS\Helpers\Form\Text( 'plugin_name', $this->name, TRUE, array( 'maxLength' => 128 ) ) );
$form->add( new \IPS\Helpers\Form\Text( 'plugin_location', $this->location, FALSE, array( 'disabled' => $this->_id ? TRUE : FALSE, 'maxLength' => 80, 'regex' => '/^[a-z][a-z0-9]*$/i' ) ) );
$form->add( new \IPS\Helpers\Form\Url( 'plugin_update_check', $this->update_check ) );
$form->addHeader( 'plugin_author_details' );
@@ -257,8 +292,8 @@ CODE;
foreach ( array( 'hooks', 'dev', 'dev/html', 'dev/css', 'dev/js', 'dev/resources', 'dev/setup' ) as $k )
{
@\mkdir( \IPS\ROOT_PATH . "/plugins/{$values['plugin_location']}/{$k}" );
\file_put_contents( \IPS\ROOT_PATH . "/plugins/{$values['plugin_location']}/hooks/index.html", '' );
@\chmod( \IPS\ROOT_PATH . "/plugins/{$values['plugin_location']}/hooks", \IPS\IPS_FOLDER_PERMISSION );
\file_put_contents( \IPS\ROOT_PATH . "/plugins/{$values['plugin_location']}/{$k}/index.html", '' );
@\chmod( \IPS\ROOT_PATH . "/plugins/{$values['plugin_location']}/{$k}", \IPS\IPS_FOLDER_PERMISSION );
}
\file_put_contents( \IPS\ROOT_PATH . "/plugins/{$values['plugin_location']}/settings.rename.php", $defaultSettings );
@@ -367,7 +402,7 @@ CODE;
$defaultButtons = parent::getButtons( $url );
/* Add a settings button */
if ( file_exists( \IPS\ROOT_PATH . '/plugins/' . $this->location . '/settings.php' ) and \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'applications', 'plugins_edit' ) )
if ( file_exists( \IPS\SITE_FILES_PATH . '/plugins/' . $this->location . '/settings.php' ) and \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'applications', 'plugins_edit' ) )
{
$buttons['settings'] = array(
'icon' => 'pencil',
@@ -378,7 +413,7 @@ CODE;
}
/* Upgrade */
if( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'applications', 'plugins_install' ) )
if( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'applications', 'plugins_install' ) AND !$this->marketplace_id )
{
$buttons['upgrade'] = array(
'icon' => 'upload',
@@ -429,7 +464,7 @@ CODE;
$buttons['download'] = array(
'icon' => 'download',
'title' => 'download',
'link' => \IPS\Http\Url::internal( "app=core&module=applications&controller=plugins&do=download&id={$this->_id}" ),
'link' => \IPS\Http\Url::internal( "app=core&module=applications&controller=plugins&do=download&id={$this->_id}" )->csrf(),
);
}
@@ -455,7 +490,7 @@ CODE;
{
$released = NULL;
if( $data['released'] AND intval( $data['released'] ) == $data['released'] AND \strlen( $data['released'] ) == 10 )
if( $data['released'] AND \intval( $data['released'] ) == $data['released'] AND \strlen( $data['released'] ) == 10 )
{
$released = (string) \IPS\DateTime::ts( $data['released'] )->localeDate();
}
@@ -527,33 +562,40 @@ CODE;
}
/* Remove the plugin directory */
if ( file_exists( \IPS\ROOT_PATH . '/plugins/' . $this->location ) )
if ( file_exists( \IPS\SITE_FILES_PATH . '/plugins/' . $this->location ) )
{
if ( file_exists( \IPS\ROOT_PATH . '/plugins/' . $this->location . '/uninstall.php') )
if ( file_exists( \IPS\SITE_FILES_PATH . '/plugins/' . $this->location . '/uninstall.php') )
{
require_once \IPS\ROOT_PATH . '/plugins/' . $this->location . '/uninstall.php';
require_once \IPS\SITE_FILES_PATH . '/plugins/' . $this->location . '/uninstall.php';
}
try
if ( \IPS\CIC2 )
{
$iterator = new \RecursiveDirectoryIterator( \IPS\ROOT_PATH . '/plugins/' . $this->location, \FilesystemIterator::SKIP_DOTS );
foreach ( new \RecursiveIteratorIterator( $iterator, \RecursiveIteratorIterator::CHILD_FIRST ) as $file )
{
if ( $file->isDir() )
\IPS\Cicloud\folderDelete( "plugins/{$this->location}" );
}
else
{
try
{
$iterator = new \RecursiveDirectoryIterator( \IPS\SITE_FILES_PATH. '/plugins/' . $this->location, \FilesystemIterator::SKIP_DOTS );
foreach ( new \RecursiveIteratorIterator( $iterator, \RecursiveIteratorIterator::CHILD_FIRST ) as $file )
{
@rmdir( $file->getPathname() );
if ( $file->isDir() )
{
@rmdir( $file->getPathname() );
}
else
{
@unlink( $file->getPathname() );
}
}
else
{
@unlink( $file->getPathname() );
}
$dir = \IPS\SITE_FILES_PATH . '/plugins/' . $this->location;
$handle = opendir( $dir );
closedir ( $handle );
@rmdir( $dir );
}
$dir = \IPS\ROOT_PATH . '/plugins/' . $this->location;
$handle = opendir( $dir );
closedir ( $handle );
@rmdir( $dir );
catch( \UnexpectedValueException $e ){}
}
catch( \UnexpectedValueException $e ){}
}
/* Delete stuff */
@@ -720,7 +762,7 @@ CODE;
if ( $depth == 2 and $closeBraces )
{
$contents .= "{$tabs}}\n{$tabs}catch ( \RuntimeException \$e )\n{$tabs}{\n{$tabs}\tif ( method_exists( get_parent_class(), __FUNCTION__ ) )\n{$tabs}\t{\n{$tabs}\t\treturn call_user_func_array( 'parent::' . __FUNCTION__, func_get_args() );\n{$tabs}\t}\n{$tabs}\telse\n{$tabs}\t{\n{$tabs}\t\tthrow \$e;\n{$tabs}\t}\n{$tabs}}\n";
$contents .= "{$tabs}}\n{$tabs}catch ( \RuntimeException \$e )\n{$tabs}{\n{$tabs}\tif ( method_exists( get_parent_class(), __FUNCTION__ ) )\n{$tabs}\t{\n{$tabs}\t\treturn \\call_user_func_array( 'parent::' . __FUNCTION__, \\func_get_args() );\n{$tabs}\t}\n{$tabs}\telse\n{$tabs}\t{\n{$tabs}\t\tthrow \$e;\n{$tabs}\t}\n{$tabs}}\n";
$depth--;
}
@@ -757,4 +799,38 @@ CODE;
return $contents;
}
/**
* Build hooks for an plugin
*
* @return void
* @throws \RuntimeException
*/
public function buildHooks()
{
if( !\IPS\IN_DEV )
{
return;
}
/* Build data */
$data = array();
foreach ( \IPS\Db::i()->select( '*', 'core_hooks', array( 'plugin=?', $this->id ) ) as $hook )
{
$data[ $hook['filename'] ] = array(
'type' => $hook['type'],
'class' => $hook['class'],
);
}
/* Write it */
try
{
\IPS\Application::writeJson( \IPS\ROOT_PATH . '/plugins/' . $this->location . '/dev/hooks.json', $data );
}
catch ( \RuntimeException $e )
{
throw new \RuntimeException( \IPS\Member::loggedIn()->language()->addToStack('dev_could_not_write_data') );
}
}
}