Version 4.3.0

This commit is contained in:
Neo committed 2025-12-19 05:47:12 -08:00
1 parent 96997ddd8e
commit fe1acf984a
1349 files changed
+116159 -67711

No files matched your search

@@ -53,7 +53,12 @@ class _ajax extends \IPS\Dispatcher\Controller
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 )
{
$record = $class::constructFromData( $row );
if ( ! $record->canView() )
{
continue;
}
if ( $database->use_categories )
{
$category = \IPS\Member::loggedIn()->language()->addToStack( 'cms_autocomplete_category', NULL, array( 'sprintf' => array( $record->container()->_title ) ) );
@@ -79,7 +79,7 @@ class _category extends \IPS\cms\Databases\Controller
try
{
$category = $catClass::loadAndCheckPerms( \IPS\cms\Databases\Dispatcher::i()->categoryId, 'read' );
$category = $catClass::loadAndCheckPerms( \IPS\cms\Databases\Dispatcher::i()->categoryId );
}
catch ( \OutOfRangeException $e )
{
@@ -169,17 +169,20 @@ class _category extends \IPS\cms\Databases\Controller
$where = NULL;
}
$table = new \IPS\Helpers\Table\Content( 'IPS\cms\Records' . \IPS\cms\Databases\Dispatcher::i()->databaseId, $category->url(), $where, $category, NULL, 'view', isset( \IPS\Request::i()->rss ) ? FALSE : TRUE );
$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 );
$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->hover = TRUE;
$table->sortBy = ( isset( \IPS\Request::i()->sortby ) ) ? \IPS\Request::i()->sortby : ( $database->field_sort ? $database->field_sort : 'record_last_comment' );
$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->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( $RecordsClass::contentCount( $category, FALSE ), $database->recordWord( $RecordsClass::contentCount( $category, FALSE ) ) ) ) );
foreach( $customFields as $id => $obj )
/* 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 == 'field_' . $id )
{
@@ -269,7 +272,7 @@ class _category extends \IPS\cms\Databases\Controller
unset ( $table->sortOptions['last_comment'] );
unset ( $table->sortOptions['num_comments'] );
}
if ( !$database->options['reviews'] )
{
unset ( $table->sortOptions['num_reviews'] );
@@ -424,7 +427,7 @@ class _category extends \IPS\cms\Databases\Controller
$table->sortDirection = $values['sort_direction'];
}
/* Cutoff */
$days = NULL;
if ( isset( $values['time_frame'] ) )
@@ -540,7 +543,7 @@ class _category extends \IPS\cms\Databases\Controller
$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 ) ) ) );
$form = $recordClass::create( $category );
$form->class = 'ipsForm_vertical';
@@ -561,7 +564,7 @@ class _category extends \IPS\cms\Databases\Controller
\IPS\Output::i()->allowDefaultWidgets = FALSE;
\IPS\Output::i()->sidebar['enabled'] = FALSE;
\IPS\cms\Pages\Page::$currentPage->getWidgets();
\IPS\cms\Databases\Dispatcher::i()->output = $form->customTemplate( array( call_user_func_array( array( \IPS\cms\Theme::i(), 'getTemplate' ), array( $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 = $form->customTemplate( array( call_user_func_array( array( \IPS\cms\Theme::i(), 'getTemplate' ), array( $database->template_form, 'cms', 'database' ) ), 'recordForm' ), NULL, $category, $database, \IPS\cms\Pages\Page::$currentPage, $title, $hasModOptions );
\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' ) );
@@ -31,6 +31,14 @@ class _index extends \IPS\cms\Databases\Controller
*/
public function manage()
{
/* 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 )
{
$pages = new \IPS\cms\modules\front\pages\page;
return $pages->manage();
}
$database = \IPS\cms\Databases::load( \IPS\cms\Databases\Dispatcher::i()->databaseId );
/* Not using categories? */
@@ -103,7 +111,7 @@ class _index extends \IPS\cms\Databases\Controller
$where = ( $database->featured_settings['featured'] ) ? array( array( 'record_featured=?', 1 ) ) : NULL;
if ( isset( $database->featured_settings['categories'] ) and count( $database->featured_settings['categories'] ) AND is_array( $database->featured_settings['categories'] ) )
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'] ) ) );
@@ -182,8 +182,8 @@ class _record extends \IPS\Content\Controller
'url' => (string) $record->url(),
'discussionUrl' => (string) $record->url(),
'mainEntityOfPage' => (string) $record->url(),
'name' => htmlspecialchars( $record->_title, ENT_QUOTES | \IPS\HTMLENTITIES, 'UTF-8', FALSE ),
'headline' => htmlspecialchars( $record->_title, ENT_QUOTES | \IPS\HTMLENTITIES, 'UTF-8', FALSE ),
'name' => $record->_title,
'headline' => $record->_title,
'text' => strip_tags( $record->truncated() ),
'articleBody' => strip_tags( $record->truncated() ),
'dateCreated' => \IPS\DateTime::ts( $record->record_saved )->format( \IPS\DateTime::ISO8601 ),
@@ -191,20 +191,19 @@ class _record extends \IPS\Content\Controller
'dateModified' => \IPS\DateTime::ts( $record->record_edit_time ?: ( $record->record_publish_date ?: $record->record_saved ) )->format( \IPS\DateTime::ISO8601 ),
'pageStart' => 1,
'pageEnd' => $record->commentPageCount(),
/* Image is required */
'image' => $record->record_image ? (string) \IPS\File::get( 'cms_Records', $record->record_image )->url : \IPS\Member::load( $record->member_id )->get_photo(),
'author' => array(
'@type' => 'Person',
'name' => htmlspecialchars( \IPS\Member::load( $record->member_id )->name, ENT_QUOTES | \IPS\HTMLENTITIES, 'UTF-8', FALSE ),
'url' => (string) \IPS\Member::load( $record->member_id )->url(),
'name' => \IPS\Member::load( $record->member_id )->name,
'image' => \IPS\Member::load( $record->member_id )->get_photo()
),
'publisher' => array(
'@type' => 'Organization',
'name' => htmlspecialchars( \IPS\Member::load( $record->member_id )->name, ENT_QUOTES | \IPS\HTMLENTITIES, 'UTF-8', FALSE ),
'url' => (string) \IPS\Member::load( $record->member_id )->url(),
'name' => \IPS\Member::load( $record->member_id )->name,
'image' => \IPS\Member::load( $record->member_id )->get_photo(),
'logo' => \IPS\Member::load( $record->member_id )->get_photo()
'logo' => array(
'@type' => 'ImageObject',
'url' => \IPS\Member::load( $record->member_id )->get_photo(),
)
),
'interactionStatistic' => array(
array(
@@ -220,6 +219,44 @@ class _record extends \IPS\Content\Controller
),
);
/* Do we have a real author? */
if( $record->member_id )
{
\IPS\Output::i()->jsonLd['article']['author']['url'] = (string) \IPS\Member::load( $record->member_id )->url();
\IPS\Output::i()->jsonLd['article']['publisher']['url'] = (string) \IPS\Member::load( $record->member_id )->url();
}
/* Image is required */
if( $record->record_image )
{
try
{
$imageObj = \IPS\File::get( 'cms_Records', $record->record_image );
$imageDims = $imageObj->getImageDimensions();
\IPS\Output::i()->jsonLd['article']['image'] = array(
'@type' => 'ImageObject',
'url' => (string) $imageObj->url,
'width' => $imageDims[0],
'height' => $imageDims[1]
);
}
/* File doesn't exist */
catch ( \RuntimeException $e ){}
catch ( \DomainException $e ){}
}
else
{
$photoVars = explode( 'x', \IPS\THUMBNAIL_SIZE );
\IPS\Output::i()->jsonLd['article']['image'] = array(
'@type' => 'ImageObject',
'url' => \IPS\Member::load( $record->member_id )->get_photo(),
'width' => $photoVars[0],
'height' => $photoVars[1]
);
}
if( $record->averageReviewRating() )
{
\IPS\Output::i()->jsonLd['article']['aggregateRating'] = array(
@@ -230,6 +267,14 @@ class _record extends \IPS\Content\Controller
'bestRating' => \IPS\Settings::i()->reviews_rating_out_of
);
}
elseif( $record->container()->allow_rating )
{
\IPS\Output::i()->jsonLd['article']['aggregateRating'] = array(
'@type' => 'AggregateRating',
'ratingValue' => $record->averageRating(),
'ratingCount' => $record->numberOfRatings(),
);
}
if( $record::database()->options['reviews'] )
{
@@ -251,7 +296,15 @@ class _record extends \IPS\Content\Controller
}
\IPS\Output::i()->contextualSearchOptions = array();
\IPS\Output::i()->contextualSearchOptions[ \IPS\Member::loggedIn()->language()->addToStack( 'search_contextual_item', FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->addToStack( $record::$title ) ) ) ) ] = array( 'type' => mb_strtolower( str_replace( '\\', '_', mb_substr( $class, 4 ) ) ), 'nodes' => $record->_id );
\IPS\Output::i()->contextualSearchOptions[ \IPS\Member::loggedIn()->language()->addToStack( 'search_contextual_item', FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->addToStack( $record::$title ) ) ) ) ] = array( 'type' => mb_strtolower( str_replace( '\\', '_', mb_substr( get_class( $record ), 4 ) ) ), 'item' => $record->_id );
try
{
$container = $record->container();
\IPS\Output::i()->contextualSearchOptions[ \IPS\Member::loggedIn()->language()->addToStack( 'search_contextual_item_categories' ) ] = array( 'type' => mb_strtolower( str_replace( '\\', '_', mb_substr( get_class( $record ), 4 ) ) ), 'nodes' => $container->_id );
}
catch ( \BadMethodCallException $e ) { }
\IPS\cms\Databases\Dispatcher::i()->output .= \IPS\cms\Theme::i()->getTemplate( $record->container()->_template_display, 'cms', 'database' )->record( $record, $comments, $form, $nextUnread );
}
@@ -58,7 +58,15 @@ class _topic extends \IPS\Dispatcher\Controller
'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 );
/* Set Breadcrumb */
foreach ( $this->topic->container()->parents() as $parent )
{
\IPS\Output::i()->breadcrumb[] = array( $parent->url(), $parent->_title );
}
\IPS\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;
}
@@ -152,12 +160,21 @@ class _topic extends \IPS\Dispatcher\Controller
$contentField = "field_{$database->field_content}";
$fakeRecord = new $recordClass;
$fakeRecord->$titleField = $this->topic->mapped('title');
$fakeRecord->$contentField = $this->topic->content();
$fakeRecord->$titleField = $this->topic->mapped('title');
$fakeRecord->$contentField = $this->topic->content();
$fakeRecord->category_id = \IPS\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() );
}
else
{
\IPS\Member::loggedIn()->language()->words['copy_comments_desc'] = sprintf( \IPS\Member::loggedIn()->language()->get( 'copy_comments_desc' ), $recordClass::_definiteArticle() );
}
\IPS\Member::loggedIn()->language()->words['copy_comments_desc'] = sprintf( \IPS\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() );
$form = new \IPS\Helpers\Form;
$form->class = 'ipsForm_vertical';
$form->hiddenValues['record_category_id'] = $category->_id;
@@ -175,7 +192,14 @@ class _topic extends \IPS\Dispatcher\Controller
if ( $database->options['comments'] )
{
$form->add( new \IPS\Helpers\Form\YesNo( 'copy_comments', FALSE ) );
$form->add( new \IPS\Helpers\Form\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 )
{
return \IPS\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 ) );
@@ -188,9 +212,29 @@ class _topic extends \IPS\Dispatcher\Controller
$comments = $values['copy_comments'];
unset( $values['copy_comments'] );
}
/* Determine if we are showing a meta message after */
$metaMessage = NULL;
/* We will only be sowing the message if we are copying comments */
if( $comments )
{
if ( array_key_exists( 'comments_show_message', $values ) )
{
$metaMessage = array( 'show' => $values['comments_show_message'], 'message' => $values['comments_meta_message'], 'color' => $values['comments_meta_color'] );
}
}
unset( $values['comments_show_message'], $values['comments_meta_message'], $values['comments_meta_color'] );
/* Figure out author */
$author = $values['copy_author'];
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 )
{
$recordClass::$skipTopicCreation = true;
}
$record = $recordClass::createFromForm( $values, $category );
@@ -198,10 +242,40 @@ class _topic extends \IPS\Dispatcher\Controller
{
$record->changeAuthor( $this->topic->author() );
}
if ( $comments )
if( $metaMessage !== NULL )
{
\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 )->setQueryString( array( 'record_id' => $record->primary_id_field, 'database_id' => $database->_id ) ) );
if( $metaMessage['show'] )
{
$id = $record->addMessage( $metaMessage['message'], $metaMessage['color'] );
\IPS\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 )
{
$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();
try
{
/* If the database is on a page, go to the record */
\IPS\Output::i()->redirect( $record->url() );
}
catch( \LogicException $e )
{
/* If it is NOT then go back to the topic */
\IPS\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 ) ) );
}
else
{
@@ -257,7 +331,9 @@ class _topic extends \IPS\Dispatcher\Controller
*/
protected function comments()
{
$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 )->setQueryString( array( 'database_id' => \IPS\Request::i()->database_id, 'record_id' => \IPS\Request::i()->record_id ) ), function( $data ) {
\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;
$commentClass = $recordClass::$commentClass;