Version 4.3.6

This commit is contained in:
Neo committed 2025-12-19 05:49:12 -08:00
1 parent fe1acf984a
commit 1a0c7fd3c2
609 files changed
+14707 -5726

No files matched your search

+1 -1
View File
@@ -818,7 +818,7 @@ EOF;
}
else
{
$theValue[] = $eachValue;
$theValue[ $eachKey ] = $eachValue;
}
}
$v = $theValue;
@@ -159,9 +159,9 @@ class _Categories extends \IPS\Node\Model implements \IPS\Node\Permissions
protected static $loadedCatsFromPath = array();
/**
* @brief [Records] Database object
* @brief [Records] Database objects
*/
protected static $database = NULL;
protected static $database = array();
/**
* @brief Latest posted record
@@ -223,12 +223,12 @@ class _Categories extends \IPS\Node\Model implements \IPS\Node\Permissions
*/
public static function database()
{
if ( static::$database === NULL )
if ( !isset( static::$database[ static::$customDatabaseId ] ) )
{
static::$database = \IPS\cms\Databases::load( static::$customDatabaseId );
static::$database[ static::$customDatabaseId ] = \IPS\cms\Databases::load( static::$customDatabaseId );
}
return static::$database;
return static::$database[ static::$customDatabaseId ];
}
/**
@@ -793,6 +793,20 @@ class _Categories extends \IPS\Node\Model implements \IPS\Node\Permissions
return parent::canDelete();
}
/**
* Save Changed Columns
*
* @return void
*/
public function save()
{
if ( !$this->_new AND isset( $this->changed['can_view_others'] ) )
{
$this->updateSearchIndexPermissions();
}
parent::save();
}
/**
* Delete
*
@@ -1002,13 +1016,13 @@ class _Categories extends \IPS\Node\Model implements \IPS\Node\Permissions
/**
* Get URL
*
* @return \IPS\Http\Url
* @return \IPS\Http\Url|NULL
*/
public function url()
{
if( $this->_url === NULL )
{
if ( \IPS\cms\Pages\Page::$currentPage and static::database()->page_id == \IPS\cms\Pages\Page::$currentPage->id )
if ( \IPS\cms\Pages\Page::$currentPage and \IPS\cms\Databases::load( $this->database_id )->page_id == \IPS\cms\Pages\Page::$currentPage->id )
{
$pagePath = \IPS\cms\Pages\Page::$currentPage->full_path;
}
@@ -812,10 +812,7 @@ class _Databases extends \IPS\Node\Model implements \IPS\Node\Permissions
parent::save();
/* Clear cache */
if ( isset( \IPS\Data\Store::i()->cms_databases ) )
{
unset( \IPS\Data\Store::i()->cms_databases );
}
unset( \IPS\Data\Store::i()->cms_databases );
/* If this database isn't searchable, make sure its content is not in the search index */
if( $removeSearchIndex )
@@ -860,11 +857,6 @@ class _Databases extends \IPS\Node\Model implements \IPS\Node\Permissions
{
$field->delete( TRUE );
}
if ( isset( \IPS\Data\Store::i()->cms_databases ) )
{
unset( \IPS\Data\Store::i()->cms_databases );
}
/* Delete comments */
\IPS\Db::i()->delete( 'cms_database_comments', array( 'comment_database_id=?', $this->id ) );
@@ -926,17 +918,18 @@ class _Databases extends \IPS\Node\Model implements \IPS\Node\Permissions
\IPS\Lang::deleteCustom( 'cms', "cms_records" . $this->id . '_pl' );
\IPS\Lang::deleteCustom( 'cms', "module__cms_records" . $this->id );
/* Unclaim attachments */
/* Unclaim attachments */
\IPS\File::unclaimAttachments( 'cms_Records', NULL, NULL, $this->id );
\IPS\File::unclaimAttachments( 'cms_Records' . $this->id );
/* Remove widgets */
$this->removeWidgets();
/* Best remove the stored data */
unset( \IPS\Data\Store::i()->database_reciprocal_links );
/* Delete the database record */
parent::delete();
/* Best remove the stored data */
unset( \IPS\Data\Store::i()->database_reciprocal_links, \IPS\Data\Store::i()->cms_databases );
}
/**
@@ -983,10 +976,7 @@ class _Databases extends \IPS\Node\Model implements \IPS\Node\Permissions
parent::setPermissions( $insert, $matrix );
/* Clear cache */
if ( isset( \IPS\Data\Store::i()->cms_databases ) )
{
unset( \IPS\Data\Store::i()->cms_databases );
}
unset( \IPS\Data\Store::i()->cms_databases );
/* Clone these permissions to all categories that do not have permissions */
$class = '\IPS\cms\Categories' . $this->id;
+45 -13
View File
@@ -400,17 +400,7 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
{
$customValidationCode = function( $val ) use ( $database, $row, $record )
{
$where = array( array( 'field_' . $row->id . '=?', $val ) );
if ( $record !== NULL )
{
$where[] = array( 'primary_id_field != ?', $record->_id );
}
if ( \IPS\Db::i()->select( 'COUNT(*)', 'cms_custom_database_' . $database->id, $where )->first() )
{
throw new \LogicException( \IPS\Member::loggedIn()->language()->addToStack( "field_unique_entry_not_unique", FALSE, array( 'sprintf' => array( $database->recordWord( 1 ) ) ) ) );
}
call_user_func_array( 'IPS\cms\Fields' . static::$customDatabaseId . '::validateUnique', array( $val, $row, $record ) );
};
}
@@ -996,6 +986,32 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
}
}
/**
* Checks to see if this value is unique
* Used in custom validation for fomr helpers
*
* @param string $val The value to check
* @param \IPS\cms\Fields $field The field
* @param \IPS\cms\Records $record The record (if any)
* @throws \LogicException
*/
public static function validateUnique( $val, $field, $record )
{
$database = \IPS\cms\Databases::load( static::$customDatabaseId );
$where = array( array( 'field_' . $field->id . '=?', $val ) );
if ( $record !== NULL )
{
$where[] = array( 'primary_id_field != ?', $record->_id );
}
if ( \IPS\Db::i()->select( 'COUNT(*)', 'cms_custom_database_' . $database->id, $where )->first() )
{
throw new \LogicException( \IPS\Member::loggedIn()->language()->addToStack( "field_unique_entry_not_unique", FALSE, array( 'sprintf' => array( $database->recordWord( 1 ) ) ) ) );
}
}
/**
* [ActiveRecord] Duplicate
*
@@ -2737,7 +2753,10 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
{
unset( \IPS\Data\Store::i()->$key );
}
/* Remove reciprocal map data */
\IPS\Db::i()->delete( 'cms_database_fields_reciprocal_map', array( 'map_origin_database_id=? AND map_field_id=? ', static::$customDatabaseId, $this->id ) );
/* Best remove the stored data */
unset( \IPS\Data\Store::i()->database_reciprocal_links );
@@ -2996,7 +3015,20 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
{
case 'Text':
case 'TextArea':
$customValidationCode = 'IPS\cms\Fields' . static::$customDatabaseId . '::validateInput_' . $this->id;
if ( $this->unique )
{
$field = $this;
$customValidationCode = function( $val ) use ( $field, $record )
{
call_user_func_array( 'IPS\cms\Fields' . static::$customDatabaseId . '::validateUnique', array( $val, $field, $record ) );
return call_user_func( 'IPS\cms\Fields' . static::$customDatabaseId . '::validateInput_' . $field->id, $val );
};
}
else
{
$customValidationCode = 'IPS\cms\Fields' . static::$customDatabaseId . '::validateInput_' . $this->id;
}
break;
}
}
+8 -1
View File
@@ -276,7 +276,7 @@ class _Media extends \IPS\Node\Model
public function form( &$form )
{
/* Build form */
$form->add( new \IPS\Helpers\Form\Upload( 'media_filename', ( ( $this->filename ) ? \IPS\File::get( 'cms_Media', $this->file_object ) : NULL ), FALSE, array( 'obscure' => FALSE, 'maxFileSize' => 5, 'storageExtension' => 'core_Theme', 'storageContainer' => 'pages_media' ), NULL, NULL, NULL, 'media_filename' ) );
$form->add( new \IPS\Helpers\Form\Upload( 'media_filename', ( ( $this->filename ) ? \IPS\File::get( 'cms_Media', $this->file_object ) : NULL ), FALSE, array( 'obscure' => FALSE, 'maxFileSize' => 5, 'storageExtension' => 'cms_Media', 'storageContainer' => 'pages_media' ), NULL, NULL, NULL, 'media_filename' ) );
$form->add( new \IPS\Helpers\Form\Node( 'media_parent', $this->parent ? $this->parent : 0, FALSE, array(
'class' => '\IPS\cms\Media\Folder',
@@ -379,6 +379,13 @@ class _Media extends \IPS\Node\Model
*/
public static function exportDesignersModeMedia()
{
/* Make sure our media folder exists */
if ( !is_dir( \IPS\ROOT_PATH . '/themes/cms/media' ) )
{
mkdir( \IPS\ROOT_PATH . '/themes/cms/media', \IPS\IPS_FOLDER_PERMISSION );
chmod( \IPS\ROOT_PATH . '/themes/cms/media', \IPS\IPS_FOLDER_PERMISSION );
}
foreach( \IPS\Db::i()->select( '*', 'cms_media' ) as $media )
{
/* We could use recursive mode but it wouldn't correctly chmod the intermediate dirs */
+9 -1
View File
@@ -1045,7 +1045,7 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
$template = \IPS\cms\Templates::load( $key );
$return[ $thing ][ $key ] = \IPS\Http\Url::createFromString( \IPS\Http\Url::baseUrl() . "/applications/cms/interface/developer/developer.php" )
->setQueryString( 'file', '/themes/cms/' . $template->location . '/' . $template->group . '/' . $template->title );
->setQueryString( 'file', 'cms/' . $template->location . '/' . $template->group . '/' . $template->title );
}
catch( \OutOfRangeException $e )
{
@@ -1933,6 +1933,11 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
*/
public function mapToDatabase( $databaseId )
{
/* Ensure this page has an ID (as in, $page->save() has not been called yet on a new page) */
if ( ! $this->id )
{
throw new \LogicException('cms_err_page_id_is_empty');
}
try
{
/* is this page already in use */
@@ -2021,6 +2026,9 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
unset( \IPS\Data\Store::i()->frontNavigation );
/* Remove any widgets for this page */
\IPS\Db::i()->delete( 'cms_page_widget_areas', array( 'area_page_id=?', $this->id ) );
parent::delete();
if ( $this->full_path and \IPS\Theme::designersModeEnabled() )
+60 -5
View File
@@ -1812,6 +1812,7 @@ class _Records extends \IPS\Content\Item implements
$class = '\IPS\cms\Categories' . static::$customDatabaseId;
$category = $class::load( $this->category_id );
$category->setLastComment();
$category->setLastReview();
$category->save();
}
}
@@ -2256,7 +2257,11 @@ class _Records extends \IPS\Content\Item implements
if ( $topic === NULL )
{
$this->syncTopic();
try
{
$this->syncTopic();
}
catch( \Exception $ex ) { }
/* Try again */
$topic = $this->topic( FALSE );
@@ -2323,7 +2328,11 @@ class _Records extends \IPS\Content\Item implements
}
else if ( $this->_forum_forum )
{
$this->syncTopic();
try
{
$this->syncTopic();
}
catch( \Exception $ex ) { }
}
}
}
@@ -2368,7 +2377,11 @@ class _Records extends \IPS\Content\Item implements
}
elseif ( $this->_forum_forum and ! $this->isFutureDate() )
{
$this->syncTopic();
try
{
$this->syncTopic();
}
catch( \Exception $ex ) { };
}
}
}
@@ -2443,6 +2456,35 @@ class _Records extends \IPS\Content\Item implements
return FALSE;
}
/**
* Is this topic linked to a record?
*
* @param \IPS\forums\Topic $topic Forums topic
* @return \IPS\cms\Records|NULL
*/
public static function getLinkedRecord( $topic )
{
foreach( \IPS\cms\Databases::databases() as $database )
{
try
{
if ( $database->forum_record and $database->forum_forum == $topic->container()->_id )
{
$class = '\IPS\cms\Records' . $database->id;
$record = $class::load( $topic->tid, 'record_topicid' );
if ( $record->_forum_record )
{
return $record;
}
}
}
catch( \Exception $e ) { }
}
return NULL;
}
/**
* Get Topic (checks member's permissions)
*
@@ -2465,10 +2507,10 @@ class _Records extends \IPS\Content\Item implements
return NULL;
}
/**
* Post this record as a forum topic
*
*
* @return void
*/
public function syncTopic()
@@ -2488,6 +2530,19 @@ class _Records extends \IPS\Content\Item implements
throw new \UnexpectedValueException('content_record_bad_forum_for_topic');
}
/* Run a test for the record url, this call will throw an LogicException if the database isn't associated to a page */
try
{
$this->url();
}
catch ( \LogicException $e )
{
$idColumn = static::$databaseColumnId;
\IPS\Log::log( sprintf( "Record %s in database %s tried to sync the topic, but failed because it has no valid url", $this->$idColumn , static::$customDatabaseId), 'cms_topicsync' );
return;
}
/* Existing topic */
if ( $this->record_topicid )
{
@@ -680,7 +680,7 @@ class _Templates extends \IPS\Patterns\ActiveRecord
$content = $this->content;
/* Build on demand */
if ( $this->type != 'js' and ( mb_stristr( $this->content, "{block=" ) or mb_stristr( $this->content, "{{if" ) ) )
if ( $this->type != 'js' and ( mb_stristr( $this->content, "{block=" ) or mb_stristr( $this->content, "{{if" ) or mb_stristr( $this->content, "{media=" ) ) )
{
$functionName = 'css_' . mt_rand();
\IPS\Theme::makeProcessFunction( str_replace( '\\', '\\\\', $content ), $functionName );