Version 4.5.0
This commit is contained in:
1 parent
1a0c7fd3c2
commit
f79dcf067a
3791 files changed
+248032
-76372
No files matched your search
@@ -12,7 +12,7 @@
|
||||
namespace IPS\cms\modules\admin\databases;
|
||||
|
||||
/* 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;
|
||||
@@ -23,6 +23,11 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
*/
|
||||
class _categories extends \IPS\Node\Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Node Class
|
||||
*/
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
namespace IPS\cms\modules\admin\databases;
|
||||
|
||||
/* 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;
|
||||
@@ -23,6 +23,11 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
*/
|
||||
class _databases extends \IPS\Node\Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Node Class
|
||||
*/
|
||||
@@ -52,23 +57,23 @@ class _databases extends \IPS\Node\Controller
|
||||
|
||||
/* Columns */
|
||||
$table->joins = array(
|
||||
array( 'select' => 'w.word_custom as database_name', 'from' => array( 'core_sys_lang_words', 'w' ), 'where' => "w.word_key=CONCAT( 'content_db_', cms_databases.database_id ) AND w.lang_id=" . \IPS\Member::loggedIn()->language()->id )
|
||||
array( 'select' => 'w.word_custom', 'from' => array( 'core_sys_lang_words', 'w' ), 'where' => "w.word_key=CONCAT( 'content_db_', cms_databases.database_id ) AND w.lang_id=" . \IPS\Member::loggedIn()->language()->id )
|
||||
);
|
||||
|
||||
$table->include = array( 'database_name', 'database_record_count', 'database_category_count' );
|
||||
$table->include = array( 'word_custom', 'database_record_count', 'database_category_count' );
|
||||
$table->widths = array(
|
||||
'database_name' => '50'
|
||||
'word_custom' => '50'
|
||||
);
|
||||
|
||||
$table->mainColumn = 'database_name';
|
||||
$table->quickSearch = 'database_name';
|
||||
$table->mainColumn = 'word_custom';
|
||||
$table->quickSearch = 'word_custom';
|
||||
|
||||
$table->sortBy = $table->sortBy ?: 'database_name';
|
||||
$table->sortBy = $table->sortBy ?: 'word_custom';
|
||||
$table->sortDirection = $table->sortDirection ?: 'asc';
|
||||
|
||||
/* Parsers */
|
||||
$table->parsers = array(
|
||||
'database_name' => function( $val, $row )
|
||||
'word_custom' => function( $val, $row )
|
||||
{
|
||||
$page = NULL;
|
||||
$database = NULL;
|
||||
@@ -247,7 +252,7 @@ class _databases extends \IPS\Node\Controller
|
||||
move_uploaded_file( $values['cms_database_import'], $tempFile );
|
||||
|
||||
/* Initate a redirector */
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=cms&module=databases&controller=databases&do=import' )->setQueryString( array( 'file' => $tempFile, 'key' => md5_file( $tempFile ) ) ) );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=cms&module=databases&controller=databases&do=import' )->setQueryString( array( 'file' => $tempFile, 'key' => md5_file( $tempFile ) ) )->csrf() );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -266,6 +271,7 @@ class _databases extends \IPS\Node\Controller
|
||||
public function import()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'databases_add' );
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
if ( !file_exists( \IPS\Request::i()->file ) or md5_file( \IPS\Request::i()->file ) !== \IPS\Request::i()->key )
|
||||
{
|
||||
@@ -273,7 +279,7 @@ class _databases extends \IPS\Node\Controller
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = new \IPS\Helpers\MultipleRedirect(
|
||||
\IPS\Http\Url::internal( 'app=cms&module=databases&controller=databases&do=import' )->setQueryString( array( 'file' => \IPS\Request::i()->file, 'key' => \IPS\Request::i()->key ) ),
|
||||
\IPS\Http\Url::internal( 'app=cms&module=databases&controller=databases&do=import' )->setQueryString( array( 'file' => \IPS\Request::i()->file, 'key' => \IPS\Request::i()->key ) )->csrf(),
|
||||
function( $data )
|
||||
{
|
||||
/* Open XML file */
|
||||
@@ -289,10 +295,10 @@ class _databases extends \IPS\Node\Controller
|
||||
/* Is this the first batch? */
|
||||
$database = null;
|
||||
$i = 0;
|
||||
if ( !is_array( $data ) )
|
||||
if ( !\is_array( $data ) )
|
||||
{
|
||||
$database = new \IPS\cms\Databases;
|
||||
$database->key = mt_rand();
|
||||
$database->key = 'import_' . mt_rand();
|
||||
$database->save();
|
||||
|
||||
/* Set default perms, these will be editable post DB import */
|
||||
@@ -435,7 +441,7 @@ class _databases extends \IPS\Node\Controller
|
||||
{
|
||||
while ( $xml->read() )
|
||||
{
|
||||
if( ! in_array( $xml->name, $areas ) OR $xml->nodeType != \XMLReader::ELEMENT )
|
||||
if( ! \in_array( $xml->name, $areas ) OR $xml->nodeType != \XMLReader::ELEMENT )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -467,7 +473,7 @@ class _databases extends \IPS\Node\Controller
|
||||
$perms = array();
|
||||
foreach( $node->attributes() as $k => $v )
|
||||
{
|
||||
if ( mb_substr( $k, 0, 5 ) === 'perm_' or in_array( $k, array( 'app', 'owner_only', 'friend_only', 'authorized_users' ) ) )
|
||||
if ( mb_substr( $k, 0, 5 ) === 'perm_' or \in_array( $k, array( 'app', 'owner_only', 'friend_only', 'authorized_users' ) ) )
|
||||
{
|
||||
$perms[ $k ] = (string) $v;
|
||||
}
|
||||
@@ -488,7 +494,7 @@ class _databases extends \IPS\Node\Controller
|
||||
|
||||
$tryJson = json_decode( $v, TRUE );
|
||||
|
||||
if ( $k === 'field_display_json' AND is_array( $tryJson ) )
|
||||
if ( $k === 'field_display_json' AND \is_array( $tryJson ) )
|
||||
{
|
||||
$displayJson = $tryJson;
|
||||
continue;
|
||||
@@ -585,14 +591,14 @@ class _databases extends \IPS\Node\Controller
|
||||
$perms = array();
|
||||
foreach( $node->attributes() as $k => $v )
|
||||
{
|
||||
if ( mb_substr( $k, 0, 5 ) === 'perm_' or in_array( $k, array( 'app', 'owner_only', 'friend_only', 'authorized_users' ) ) )
|
||||
if ( mb_substr( $k, 0, 5 ) === 'perm_' or \in_array( $k, array( 'app', 'owner_only', 'friend_only', 'authorized_users' ) ) )
|
||||
{
|
||||
$perms[ $k ] = (string) $v;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
$attrs[ $k ] = ( in_array( $k, array( 'category_parent_id' ) ) ) ? (int) $v : (string) $v;
|
||||
$attrs[ $k ] = ( \in_array( $k, array( 'category_parent_id' ) ) ) ? (int) $v : (string) $v;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -612,12 +618,13 @@ class _databases extends \IPS\Node\Controller
|
||||
/* Create a category */
|
||||
$category = new \IPS\cms\Categories;
|
||||
$category->database_id = $database->id;
|
||||
$category::$permType = 'categories_' . $database->id;
|
||||
|
||||
$category->saveForm( $category->formatFormValues( $attrs ) );
|
||||
|
||||
if ( $category->fields AND $category->fields !== '*' )
|
||||
{
|
||||
if ( is_array( $category->fields ) )
|
||||
if ( \is_array( $category->fields ) )
|
||||
{
|
||||
$field_map = \IPS\Data\Store::i()->db_import_field_map;
|
||||
$newMap = array();
|
||||
@@ -630,7 +637,7 @@ class _databases extends \IPS\Node\Controller
|
||||
}
|
||||
}
|
||||
|
||||
if ( count( $newMap ) )
|
||||
if ( \count( $newMap ) )
|
||||
{
|
||||
$category->fields = json_encode( $newMap );
|
||||
$category->save();
|
||||
@@ -784,7 +791,7 @@ class _databases extends \IPS\Node\Controller
|
||||
if ( isset( \IPS\Data\Store::i()->db_import_field_map ) )
|
||||
{
|
||||
$map = \IPS\Data\Store::i()->db_import_field_map;
|
||||
$sortId = intval( mb_substr( $database->field_sort, 6 ) );
|
||||
$sortId = \intval( mb_substr( $database->field_sort, 6 ) );
|
||||
|
||||
if ( isset( $map[ $sortId ] ) )
|
||||
{
|
||||
@@ -870,7 +877,7 @@ class _databases extends \IPS\Node\Controller
|
||||
'comment_bump', 'forum_record', 'forum_comments', 'forum_delete', 'forum_forum', 'forum_prefix', 'forum_suffix', 'search', 'tags_enabled', 'tags_noprefixes', 'tags_predefined', 'fixed_field_perms',
|
||||
'cat_index_type', 'template_form', 'template_featured', 'featured_settings', 'options' ) as $field )
|
||||
{
|
||||
if ( is_array( $database->$field ) )
|
||||
if ( \is_array( $database->$field ) )
|
||||
{
|
||||
$arrays[ $field ] = $database->$field;
|
||||
}
|
||||
@@ -881,7 +888,7 @@ class _databases extends \IPS\Node\Controller
|
||||
if ( $database->$field instanceof \IPS\Patterns\Bitwise )
|
||||
{
|
||||
$bwfield = $database->$field;
|
||||
$store = intval( $bwfield->values['options'] );
|
||||
$store = \intval( $bwfield->values['options'] );
|
||||
}
|
||||
|
||||
$xml->startAttribute( $field );
|
||||
@@ -890,7 +897,7 @@ class _databases extends \IPS\Node\Controller
|
||||
}
|
||||
}
|
||||
|
||||
if ( count( $arrays ) )
|
||||
if ( \count( $arrays ) )
|
||||
{
|
||||
foreach( $arrays as $field => $v )
|
||||
{
|
||||
@@ -927,7 +934,7 @@ class _databases extends \IPS\Node\Controller
|
||||
|
||||
foreach( $row as $k => $v )
|
||||
{
|
||||
if ( array_key_exists( $k, $fieldSchema['columns'] ) AND ! in_array( $k, $removeFields ) AND ! in_array( $k, $textFields ) )
|
||||
if ( array_key_exists( $k, $fieldSchema['columns'] ) AND ! \in_array( $k, $removeFields ) AND ! \in_array( $k, $textFields ) )
|
||||
{
|
||||
$xml->startAttribute( $k );
|
||||
$xml->text( $v );
|
||||
@@ -974,7 +981,7 @@ class _databases extends \IPS\Node\Controller
|
||||
|
||||
foreach( $row as $k => $v )
|
||||
{
|
||||
if ( array_key_exists( $k, $categorySchema['columns'] ) AND ! in_array( $k, $removeFields ) AND ! in_array( $k, $textFields ) )
|
||||
if ( array_key_exists( $k, $categorySchema['columns'] ) AND ! \in_array( $k, $removeFields ) AND ! \in_array( $k, $textFields ) )
|
||||
{
|
||||
$xml->startAttribute( $k );
|
||||
$xml->text( $v );
|
||||
@@ -1010,7 +1017,7 @@ class _databases extends \IPS\Node\Controller
|
||||
|
||||
foreach( array('template_listing', 'template_display', 'template_categories', 'template_featured') as $area )
|
||||
{
|
||||
if ( isset( $templates['cms']['database'][ $database->$area ] ) and is_array( $templates['cms']['database'][ $database->$area ] ) )
|
||||
if ( isset( $templates['cms']['database'][ $database->$area ] ) and \is_array( $templates['cms']['database'][ $database->$area ] ) )
|
||||
{
|
||||
/* Only fetch edited/added templates, no point in fetching default theme templates */
|
||||
foreach( $templates['cms']['database'][ $database->$area ] as $key => $item )
|
||||
@@ -1034,7 +1041,7 @@ class _databases extends \IPS\Node\Controller
|
||||
}
|
||||
}
|
||||
|
||||
if ( count( $toSave ) )
|
||||
if ( \count( $toSave ) )
|
||||
{
|
||||
foreach( $toSave as $group => $items )
|
||||
{
|
||||
@@ -1116,6 +1123,31 @@ class _databases extends \IPS\Node\Controller
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=cms&module=databases&controller=databases' ), 'deleted' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Permissions
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function permissions()
|
||||
{
|
||||
parent::permissions();
|
||||
|
||||
$database = \IPS\cms\Databases::load( \IPS\Request::i()->id );
|
||||
|
||||
try
|
||||
{
|
||||
if( $database->page_id AND \IPS\cms\Pages\Page::load( $database->page_id )->permissions()['perm_view'] != '*' )
|
||||
{
|
||||
/* We want the message to show at the top, so get our output as we will start over */
|
||||
$output = \IPS\Output::i()->output;
|
||||
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->message( \IPS\Member::loggedIn()->language()->addToStack('database_page_permissions_restrict', FALSE, array( 'sprintf' => array( $database->page_id ) ) ), 'warning' );
|
||||
\IPS\Output::i()->output .= $output;
|
||||
}
|
||||
}
|
||||
catch( \OutOfRangeException $e ){}
|
||||
}
|
||||
|
||||
/**
|
||||
* Promote
|
||||
*
|
||||
@@ -1161,6 +1193,8 @@ class _databases extends \IPS\Node\Controller
|
||||
*/
|
||||
public function rebuildTopicContent()
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
if ( isset( \IPS\Request::i()->process ) )
|
||||
{
|
||||
\IPS\Task::queue( 'cms', 'ResyncTopicContent', array( 'databaseId' => \IPS\Request::i()->id ), 3, array( 'databaseId' ) );
|
||||
@@ -1181,6 +1215,7 @@ class _databases extends \IPS\Node\Controller
|
||||
{
|
||||
if ( isset( \IPS\Request::i()->process ) )
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
\IPS\Task::queue( 'core', 'RebuildItemCounts', array( 'class' => 'IPS\cms\Records' . \IPS\Request::i()->id ), 3, array( 'class' ) );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=cms&module=databases&controller=databases&do=form&id=' . \IPS\Request::i()->id ), 'database_rebuild_added' );
|
||||
}
|
||||
@@ -1193,6 +1228,7 @@ class _databases extends \IPS\Node\Controller
|
||||
/**
|
||||
* Add/Edit
|
||||
*
|
||||
* @csrfChecked Uses $this->_getDatabaseForm() which uses Form Helper 7 Oct 2019
|
||||
* @return void
|
||||
*/
|
||||
public function form()
|
||||
@@ -1244,7 +1280,7 @@ class _databases extends \IPS\Node\Controller
|
||||
|
||||
if ( ! $values['database_key'] )
|
||||
{
|
||||
if ( is_array( $values['database_name'] ) )
|
||||
if ( \is_array( $values['database_name'] ) )
|
||||
{
|
||||
$keyToUse = mt_rand();
|
||||
foreach( $values['database_name'] as $langId => $word )
|
||||
@@ -1343,11 +1379,8 @@ class _databases extends \IPS\Node\Controller
|
||||
{
|
||||
$current->tags_enabled = (int) $values['database_tags_enabled'];
|
||||
$current->tags_noprefixes = !(bool) $values['database_tags_noprefixes'];
|
||||
|
||||
if ( ! \IPS\Settings::i()->tags_open_system )
|
||||
{
|
||||
$current->tags_predefined = ( is_array( $values['database_tags_predefined'] ) ) ? implode( ',', array_filter( array_map( 'trim', $values['database_tags_predefined'] ) ) ) : NULL;
|
||||
}
|
||||
$current->tags_predefined = ( \is_array( $values['database_tags_predefined'] ) ) ? implode( ',', array_filter( array_map( 'trim', $values['database_tags_predefined'] ) ) ) : NULL;
|
||||
|
||||
}
|
||||
|
||||
$categories = 0;
|
||||
@@ -1375,6 +1408,16 @@ class _databases extends \IPS\Node\Controller
|
||||
|
||||
if ( \IPS\Application::appIsEnabled( 'forums' ) )
|
||||
{
|
||||
/* Are we changing where comments go? */
|
||||
if ( !$new AND ( (int) $current->forum_record != (int) $values['database_forum_record'] OR (int) $current->forum_comments != (int) $values['database_forum_comments'] ) )
|
||||
{
|
||||
\IPS\Task::queue( 'cms', 'MoveComments', array(
|
||||
'databaseId' => $current->id,
|
||||
'to' => ( $values['database_forum_comments'] AND $values['database_forum_record'] ) ? 'forums' : 'pages',
|
||||
'deleteTopics' => (bool) ( !$values['database_forum_record'] )
|
||||
), 1, array( 'databaseId', 'to' ) );
|
||||
}
|
||||
|
||||
$current->forum_record = (int) $values['database_forum_record'];
|
||||
$current->forum_comments = (int) $values['database_forum_comments'];
|
||||
$current->forum_forum = ( ! $values['database_forum_forum'] ) ? 0 : $values['database_forum_forum']->id;
|
||||
@@ -1388,7 +1431,10 @@ class _databases extends \IPS\Node\Controller
|
||||
$current->forum_comments = 0;
|
||||
$current->forum_delete = 0;
|
||||
}
|
||||
|
||||
|
||||
/* SEO */
|
||||
$current->canonical_flag = (int) $values['database_canonical_flag'];
|
||||
|
||||
$fieldSettingJson = array();
|
||||
|
||||
foreach( $values as $k => $v )
|
||||
@@ -1429,6 +1475,7 @@ class _databases extends \IPS\Node\Controller
|
||||
$category->allow_rating = $values['category_allow_rating'];
|
||||
$category->can_view_others = $values['category_can_view_others'];
|
||||
$category->save();
|
||||
$category->cloneDatabasePermissions();
|
||||
}
|
||||
|
||||
if ( $new )
|
||||
@@ -1607,7 +1654,7 @@ class _databases extends \IPS\Node\Controller
|
||||
|
||||
foreach( $FieldsClass::data() as $id => $field )
|
||||
{
|
||||
if ( in_array( $field->type, array( 'checkbox', 'multiselect', 'attachments' ) ) )
|
||||
if ( \in_array( $field->type, array( 'checkbox', 'multiselect', 'attachments' ) ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -1646,10 +1693,10 @@ class _databases extends \IPS\Node\Controller
|
||||
|
||||
$form->addHeader( 'cms_database_form_display' );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'database_template_categories', ! empty( $current ) ? $current->template_categories : NULL, FALSE, array( 'options' => $templatesCat ), NULL, NULL, NULL, 'database_template_categories' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'database_template_listing' , ! empty( $current ) ? $current->template_listing : NULL, FALSE, array( 'options' => $templatesList ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'database_template_display' , ! empty( $current ) ? $current->template_display : NULL, FALSE, array( 'options' => $templatesDisplay ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'database_template_form' , ! empty( $current ) ? $current->template_form : NULL, FALSE, array( 'options' => $templatesForm ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'database_template_categories', ! empty( $current ) ? $current->template_categories : NULL, FALSE, array( 'options' => $templatesCat ), NULL, NULL, \IPS\Theme::i()->getTemplate( 'databases', 'cms' )->templateGoButton('database_template_categories'), 'database_template_categories' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'database_template_listing' , ! empty( $current ) ? $current->template_listing : NULL, FALSE, array( 'options' => $templatesList ), NULL, NULL, \IPS\Theme::i()->getTemplate( 'databases', 'cms' )->templateGoButton('database_template_listing'), 'database_template_listing' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'database_template_display' , ! empty( $current ) ? $current->template_display : NULL, FALSE, array( 'options' => $templatesDisplay ), NULL, NULL, \IPS\Theme::i()->getTemplate( 'databases', 'cms' )->templateGoButton('database_template_display'), 'database_template_display' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'database_template_form' , ! empty( $current ) ? $current->template_form : NULL, FALSE, array( 'options' => $templatesForm ), NULL, NULL, \IPS\Theme::i()->getTemplate( 'databases', 'cms' )->templateGoButton('database_template_form'), 'database_template_form' ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'database_key', ! empty( $current ) ? $current->key : FALSE, FALSE, array(), function( $val )
|
||||
{
|
||||
@@ -1745,10 +1792,7 @@ class _databases extends \IPS\Node\Controller
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'database_tags_enabled' , $current ? $current->tags_enabled : FALSE, FALSE, array( 'togglesOn' => array( 'database_tags_noprefixes', 'database_tags_predefined' ) ), NULL, NULL, NULL, 'database_tags_enabled' ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'database_tags_noprefixes', $current ? ! $current->tags_noprefixes : FALSE, FALSE, array(), NULL, NULL, NULL, 'database_tags_noprefixes' ) );
|
||||
if ( ! \IPS\Settings::i()->tags_open_system )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'database_tags_predefined', $current ? $current->tags_predefined: '', FALSE, array( 'autocomplete' => array( 'unique' => 'true' ), 'nullLang' => 'database_tags_predefined_unlimited' ), NULL, NULL, NULL, 'database_tags_predefined' ) );
|
||||
}
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'database_tags_predefined', $current ? $current->tags_predefined: '', FALSE, array( 'autocomplete' => array( 'unique' => 'true' ), 'nullLang' => 'database_tags_predefined_unlimited' ), NULL, NULL, NULL, 'database_tags_predefined' ) );
|
||||
}
|
||||
|
||||
$form->addHeader( 'content_database_form_options_fields' );
|
||||
@@ -1774,12 +1818,12 @@ class _databases extends \IPS\Node\Controller
|
||||
|
||||
$ffsettings = $current->fixed_field_settings;
|
||||
|
||||
if ( isset( $ffsettings['record_image']['image_dims'] ) and is_array( $ffsettings['record_image']['image_dims'] ) )
|
||||
if ( isset( $ffsettings['record_image']['image_dims'] ) and \is_array( $ffsettings['record_image']['image_dims'] ) )
|
||||
{
|
||||
$widthHeight = $ffsettings['record_image']['image_dims'];
|
||||
}
|
||||
|
||||
if ( isset( $ffsettings['record_image']['thumb_dims'] ) and is_array( $ffsettings['record_image']['thumb_dims'] ) )
|
||||
if ( isset( $ffsettings['record_image']['thumb_dims'] ) and \is_array( $ffsettings['record_image']['thumb_dims'] ) )
|
||||
{
|
||||
$thumbWidthHeight = $ffsettings['record_image']['thumb_dims'];
|
||||
}
|
||||
@@ -1857,6 +1901,17 @@ class _databases extends \IPS\Node\Controller
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'database_forum_delete' , $current ? $current->forum_delete : FALSE, FALSE, array(), NULL, NULL, NULL, 'database_forum_delete' ) );
|
||||
}
|
||||
|
||||
/* SEO */
|
||||
$form->addTab( 'content_database_form_seo' );
|
||||
$form->addHeader( 'database_canonical_header' );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'database_canonical_flag', ! empty( $current ) ? $current->canonical_flag : NULL, FALSE, array(
|
||||
'options' => array(
|
||||
'0' => 'database_canonical_flag_0',
|
||||
'1' => 'database_canonical_flag_1'
|
||||
)
|
||||
) ) );
|
||||
|
||||
if ( ! $current )
|
||||
{
|
||||
$form->addTab( 'content_database_form_options_page' );
|
||||
@@ -1920,7 +1975,7 @@ class _databases extends \IPS\Node\Controller
|
||||
|
||||
foreach( $pageFormFields as $name => $field )
|
||||
{
|
||||
if ( is_array( $field ) )
|
||||
if ( \is_array( $field ) )
|
||||
{
|
||||
$form->addHeader( $field[0] );
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
namespace IPS\cms\modules\admin\databases;
|
||||
|
||||
/* 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;
|
||||
@@ -23,6 +23,11 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
*/
|
||||
class _fields extends \IPS\Node\Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Node Class
|
||||
*/
|
||||
@@ -130,6 +135,8 @@ class _fields extends \IPS\Node\Controller
|
||||
*/
|
||||
public function enableToggle()
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
$class = '\IPS\cms\Fields' . \IPS\Request::i()->database_id;
|
||||
|
||||
$class::setFixedFieldVisibility( \IPS\Request::i()->id, (boolean) \IPS\Request::i()->status );
|
||||
@@ -152,6 +159,8 @@ class _fields extends \IPS\Node\Controller
|
||||
*/
|
||||
public function setAsTitle()
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
$class = '\IPS\cms\Fields' . \IPS\Request::i()->database_id;
|
||||
$database = \IPS\cms\Databases::load( \IPS\Request::i()->database_id );
|
||||
|
||||
@@ -180,6 +189,8 @@ class _fields extends \IPS\Node\Controller
|
||||
*/
|
||||
public function setAsContent()
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
$class = '\IPS\cms\Fields' . \IPS\Request::i()->database_id;
|
||||
$database = \IPS\cms\Databases::load( \IPS\Request::i()->database_id );
|
||||
|
||||
@@ -236,7 +247,7 @@ class _fields extends \IPS\Node\Controller
|
||||
$matrix->columns[ $k ] = function( $key, $value, $data ) use ( $perms, $k, $v )
|
||||
{
|
||||
$groupId = mb_substr( $key, 0, -( 2 + mb_strlen( $k ) ) );
|
||||
return new \IPS\Helpers\Form\Checkbox( $key, isset( $perms[ "perm_{$v}" ] ) and ( $perms[ "perm_{$v}" ] === '*' or in_array( $groupId, explode( ',', $perms[ "perm_{$v}" ] ) ) ) );
|
||||
return new \IPS\Helpers\Form\Checkbox( $key, isset( $perms[ "perm_{$v}" ] ) and ( $perms[ "perm_{$v}" ] === '*' or \in_array( $groupId, explode( ',', $perms[ "perm_{$v}" ] ) ) ) );
|
||||
};
|
||||
$matrix->checkAlls[ $k ] = ( $perms[ "perm_{$v}" ] === '*' );
|
||||
}
|
||||
@@ -276,7 +287,7 @@ class _fields extends \IPS\Node\Controller
|
||||
{
|
||||
foreach ( $permMap as $k => $v )
|
||||
{
|
||||
if ( isset( $perms[ $k ] ) and $perms[ $k ] and is_array( $_perms[ $v ] ) )
|
||||
if ( isset( $perms[ $k ] ) and $perms[ $k ] and \is_array( $_perms[ $v ] ) )
|
||||
{
|
||||
$_perms[ $v ][] = $group;
|
||||
}
|
||||
@@ -286,7 +297,7 @@ class _fields extends \IPS\Node\Controller
|
||||
/* Finalise */
|
||||
foreach ( $_perms as $k => $v )
|
||||
{
|
||||
$save[ "perm_{$k}" ] = is_array( $v ) ? implode( $v, ',' ) : $v;
|
||||
$save[ "perm_{$k}" ] = \is_array( $v ) ? implode( ',', $v ) : $v;
|
||||
}
|
||||
|
||||
$class::setFixedFieldPermissions( \IPS\Request::i()->field, $save );
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
namespace IPS\cms\modules\admin\databases;
|
||||
|
||||
/* 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;
|
||||
@@ -23,6 +23,11 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
*/
|
||||
class _records extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
@@ -362,7 +367,7 @@ class _records extends \IPS\Dispatcher\Controller
|
||||
|
||||
foreach( $formElements as $name => $field )
|
||||
{
|
||||
if ( in_array( $name, $manuallyHandledFields ) )
|
||||
if ( \in_array( $name, $manuallyHandledFields ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -411,7 +416,12 @@ class _records extends \IPS\Dispatcher\Controller
|
||||
)
|
||||
), NULL, NULL, NULL, 'record_author_choice' ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Member( 'record_member_id', ( $currentMember and $currentMember->member_id ) ? $currentMember : NULL, FALSE, array(), NULL, NULL, NULL, 'record_member_id' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Member( 'record_member_id', ( $currentMember and $currentMember->member_id ) ? $currentMember : NULL, FALSE, array(), function( $val ) {
|
||||
if( !$val AND \IPS\Request::i()->record_author_choice == 'notme' )
|
||||
{
|
||||
throw new \DomainException( 'form_required' );
|
||||
}
|
||||
}, NULL, NULL, 'record_member_id' ) );
|
||||
|
||||
if ( isset( $formElements['record_allow_comments'] ) )
|
||||
{
|
||||
@@ -487,7 +497,7 @@ class _records extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
else if ( ! $current->member_id and $values['record_author_choice'] !== 'guest' )
|
||||
{
|
||||
$values['record_member_id'] = \IPS\Member::loggedIn();
|
||||
$values['record_member_id'] = ( $values['record_author_choice'] === 'me' ) ? \IPS\Member::loggedIn() : $values['record_member_id'];
|
||||
$changeAuthor = TRUE;
|
||||
}
|
||||
else if ( $values['record_author_choice'] === 'me' )
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
namespace IPS\cms\modules\admin\pages;
|
||||
|
||||
/* 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;
|
||||
@@ -23,10 +23,15 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
*/
|
||||
class _ajax extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Return a CSS or HTML menu
|
||||
*
|
||||
* @return html
|
||||
* @return void
|
||||
*/
|
||||
public function loadMenu()
|
||||
{
|
||||
@@ -73,7 +78,7 @@ class _ajax extends \IPS\Dispatcher\Controller
|
||||
/**
|
||||
* Return HTML template as JSON
|
||||
*
|
||||
* @return string
|
||||
* @return void
|
||||
*/
|
||||
public function loadTemplate()
|
||||
{
|
||||
@@ -121,7 +126,7 @@ class _ajax extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
try
|
||||
{
|
||||
if ( is_numeric( $t_key ) )
|
||||
if ( \is_numeric( $t_key ) )
|
||||
{
|
||||
$template = \IPS\cms\Templates::load( $t_key, 'template_id' );
|
||||
}
|
||||
@@ -160,7 +165,112 @@ class _ajax extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->blankTemplate( \IPS\Theme::i()->getTemplate( 'templates', 'cms', 'admin' )->viewTemplate( $templateArray ) ), 200, 'text/html', \IPS\Output::i()->httpHeaders );
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->blankTemplate( \IPS\Theme::i()->getTemplate( 'templates', 'cms', 'admin' )->viewTemplate( $templateArray ) ), 200, 'text/html' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [AJAX] Search templates
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function searchtemplates()
|
||||
{
|
||||
\IPS\Dispatcher::i()->checkAcpPermission( 'template_manage' );
|
||||
|
||||
$where = array();
|
||||
if ( \IPS\Request::i()->term )
|
||||
{
|
||||
$where[] = array( '( LOWER(template_title) LIKE ? OR LOWER(template_content) LIKE ? )', '%' . mb_strtolower( \IPS\Request::i()->term ) . '%', '%' . mb_strtolower( \IPS\Request::i()->term ) . '%' );
|
||||
}
|
||||
|
||||
if ( ! \in_array( 'custom', explode( ',', \IPS\Request::i()->filters ) ) )
|
||||
{
|
||||
$where[] = array( 'template_master=1 OR (template_user_created=1 and template_user_edited=0)' );
|
||||
}
|
||||
|
||||
if ( ! \in_array( 'unmodified', explode( ',', \IPS\Request::i()->filters ) ) )
|
||||
{
|
||||
$where[] = array( 'template_user_created=1 and template_user_edited=1' );
|
||||
}
|
||||
|
||||
$select = \IPS\Db::i()->select(
|
||||
'*',
|
||||
'cms_templates',
|
||||
$where,
|
||||
'template_location, template_group, template_title, template_master desc'
|
||||
);
|
||||
|
||||
$return = array();
|
||||
foreach( $select as $result )
|
||||
{
|
||||
$return[ $result['template_location'] ][ $result['template_group'] ][ $result['template_key'] ] = $result['template_title'];
|
||||
}
|
||||
|
||||
\IPS\Output::i()->json( $return );
|
||||
}
|
||||
|
||||
/**
|
||||
* Load Tags
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function loadTags(): void
|
||||
{
|
||||
$page = NULL;
|
||||
if ( isset( \IPS\Request::i()->pageId ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$page = \IPS\cms\Pages\Page::load( \IPS\Request::i()->pageId );
|
||||
}
|
||||
catch( \OutOfRangeException $e ) {}
|
||||
}
|
||||
|
||||
$tags = array();
|
||||
$tagLinks = array();
|
||||
|
||||
if ( $page and $page->id == \IPS\Settings::i()->cms_error_page )
|
||||
{
|
||||
$tags['cms_error_page']['{error_message}'] = 'cms_error_page_message';
|
||||
$tags['cms_error_page']['{error_code}'] = 'cms_error_page_code';
|
||||
}
|
||||
|
||||
foreach( \IPS\cms\Databases::roots( NULL, NULL ) as $id => $db )
|
||||
{
|
||||
if ( ! $db->page_id )
|
||||
{
|
||||
$tags['cms_tag_databases']['{database="' . $db->key . '"}'] = $db->_title;
|
||||
}
|
||||
}
|
||||
|
||||
foreach( \IPS\cms\Blocks\Block::roots( NULL, NULL ) as $id => $block )
|
||||
{
|
||||
$tags['cms_tag_blocks']['{block="' . $block->key . '"}'] = $block->_title;
|
||||
}
|
||||
|
||||
foreach( \IPS\Db::i()->select( '*', 'cms_pages', NULL, 'page_full_path ASC', array( 0, 50 ) ) as $page )
|
||||
{
|
||||
$tags['cms_tag_pages']['{pageurl="' . $page['page_full_path'] . '"}' ] = \IPS\Member::loggedIn()->language()->addToStack( \IPS\cms\Pages\Page::$titleLangPrefix . $page['page_id'] );
|
||||
}
|
||||
|
||||
/* If we can manage words, then the header needs to always show */
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'languages', 'lang_words' ) )
|
||||
{
|
||||
$tags['cms_tag_lang'] = array();
|
||||
$tagLinks['cms_tag_lang'] = array(
|
||||
'icon' => 'plus',
|
||||
'title' => \IPS\Member::loggedIn()->language()->addToStack('add_word'),
|
||||
'link' => \IPS\Http\Url::internal( "app=core&module=languages&controller=languages&do=addWord" ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack( 'add_word' ), 'ipsDialog-remoteSubmit' => TRUE, 'action' => "wordForm" )
|
||||
);
|
||||
}
|
||||
|
||||
foreach( \IPS\Db::i()->select( '*', 'core_sys_lang_words', array( "word_is_custom=? AND lang_id=?", 1, \IPS\Member::loggedIn()->language()->_id ) ) AS $lang )
|
||||
{
|
||||
$tags['cms_tag_lang']['{lang="' . $lang['word_key'] . '"}'] = $lang['word_custom'] ?: $lang['word_default'];
|
||||
}
|
||||
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->blankTemplate( \IPS\Theme::i()->getTemplate( 'forms', 'core', 'global' )->editorTags( $tags, $tagLinks ) ), 200, 'text/html' );
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@
|
||||
namespace IPS\cms\modules\admin\pages;
|
||||
|
||||
/* 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;
|
||||
@@ -23,6 +23,11 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
*/
|
||||
class _blocks extends \IPS\Node\Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Node Class
|
||||
*/
|
||||
@@ -82,6 +87,7 @@ class _blocks extends \IPS\Node\Controller
|
||||
{
|
||||
if ( isset( \IPS\Request::i()->id ) )
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
\IPS\cms\Blocks\Block::deleteCompiled( \IPS\Request::i()->id );
|
||||
}
|
||||
|
||||
@@ -100,6 +106,17 @@ class _blocks extends \IPS\Node\Controller
|
||||
|
||||
return $buttons;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch any additional HTML for this row
|
||||
*
|
||||
* @param object $node Node returned from $nodeClass::load()
|
||||
* @return NULL|string
|
||||
*/
|
||||
public function _getRowHtml( $node )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'blocks', 'cms', 'admin' )->rowHtml( $node );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add block, pre form
|
||||
@@ -211,4 +228,33 @@ class _blocks extends \IPS\Node\Controller
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('block_embed_title');
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core', 'admin' )->block( '', \IPS\Theme::i()->getTemplate( 'blocks', 'cms', 'admin' )->embedCode( $block, $embedKey ) );;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load tags
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function loadTags(): void
|
||||
{
|
||||
$tags = array();
|
||||
$tagLinks = array();
|
||||
|
||||
/* If we can manage words, then the header needs to always show */
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'core', 'languages', 'lang_words' ) )
|
||||
{
|
||||
$tags['cms_tag_lang'] = array();
|
||||
$tagLinks['cms_tag_lang'] = array(
|
||||
'icon' => 'plus',
|
||||
'title' => \IPS\Member::loggedIn()->language()->addToStack('add_word'),
|
||||
'link' => \IPS\Http\Url::internal( "app=core&module=languages&controller=languages&do=addWord" ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack( 'add_word' ), 'ipsDialog-remoteSubmit' => TRUE )
|
||||
);
|
||||
}
|
||||
foreach( \IPS\Db::i()->select( '*', 'core_sys_lang_words', array( "word_is_custom=? AND lang_id=?", 1, \IPS\Member::loggedIn()->language()->_id ) ) AS $lang )
|
||||
{
|
||||
$tags['cms_tag_lang']['{lang="' . $lang['word_key'] . '"}'] = $lang['word_custom'] ?: $lang['word_default'];
|
||||
}
|
||||
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->blankTemplate( \IPS\Theme::i()->getTemplate( 'forms', 'core', 'global' )->editorTags( $tags, $tagLinks ) ), 200, 'text/html' );
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@
|
||||
namespace IPS\cms\modules\admin\pages;
|
||||
|
||||
/* 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;
|
||||
@@ -23,6 +23,11 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
*/
|
||||
class _media extends \IPS\Node\Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Node Class
|
||||
*/
|
||||
@@ -75,15 +80,17 @@ class _media extends \IPS\Node\Controller
|
||||
*/
|
||||
public function deleteByFileIds()
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
if ( isset( \IPS\Request::i()->fileIds ) )
|
||||
{
|
||||
$ids = \IPS\Request::i()->fileIds;
|
||||
|
||||
if ( ! is_array( $ids ) )
|
||||
if ( ! \is_array( $ids ) )
|
||||
{
|
||||
$try = json_decode( $ids, TRUE );
|
||||
|
||||
if ( ! is_array( $try ) )
|
||||
if ( ! \is_array( $try ) )
|
||||
{
|
||||
$ids = array( $ids );
|
||||
}
|
||||
@@ -93,7 +100,7 @@ class _media extends \IPS\Node\Controller
|
||||
}
|
||||
}
|
||||
|
||||
if ( count( $ids ) )
|
||||
if ( \count( $ids ) )
|
||||
{
|
||||
\IPS\cms\Media::deleteByFileIds( $ids );
|
||||
}
|
||||
@@ -134,7 +141,7 @@ class _media extends \IPS\Node\Controller
|
||||
}
|
||||
|
||||
if( \IPS\Request::i()->isAjax() ){
|
||||
\IPS\Output::i()->sendOutput( json_encode( $rows ), 200, 'application/json', \IPS\Output::i()->httpHeaders );
|
||||
\IPS\Output::i()->sendOutput( json_encode( $rows ), 200, 'application/json' );
|
||||
}
|
||||
|
||||
return $data;
|
||||
@@ -179,7 +186,7 @@ class _media extends \IPS\Node\Controller
|
||||
}
|
||||
|
||||
if( \IPS\Request::i()->isAjax() ){
|
||||
\IPS\Output::i()->sendOutput( json_encode( $rows ), 200, 'application/json', \IPS\Output::i()->httpHeaders );
|
||||
\IPS\Output::i()->sendOutput( json_encode( $rows ), 200, 'application/json' );
|
||||
}
|
||||
|
||||
return $rows;
|
||||
@@ -195,7 +202,7 @@ class _media extends \IPS\Node\Controller
|
||||
|
||||
if( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( $output, 200, 'text/html', \IPS\Output::i()->httpHeaders );
|
||||
\IPS\Output::i()->sendOutput( $output, 200, 'text/html' );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -228,7 +235,7 @@ class _media extends \IPS\Node\Controller
|
||||
$form = new \IPS\Helpers\Form( 'form', 'upload' );
|
||||
$form->class = 'ipsForm_vertical ipsForm_noLabels';
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Upload( 'media_filename', NULL, FALSE, array( 'allowedFileTypes' => array_merge( \IPS\File::$safeFileExtensions, array( 'pdf' ) ), 'obscure' => FALSE, 'maxFileSize' => 5, 'storageExtension' => 'cms_Media', 'storageContainer' => 'pages_media', 'multiple' => FALSE, 'minimize' => FALSE ), NULL, NULL, NULL, 'media_filename' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Upload( 'media_filename', NULL, FALSE, array( 'allowedFileTypes' => array_merge( \IPS\File::$safeFileExtensions, array( 'pdf' ) ), 'obscure' => FALSE, 'storageExtension' => 'cms_Media', 'storageContainer' => 'pages_media', 'multiple' => FALSE, 'minimize' => FALSE ), NULL, NULL, NULL, 'media_filename' ) );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
@@ -277,7 +284,7 @@ class _media extends \IPS\Node\Controller
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->sendOutput( json_encode( array( 'fileID' => $media->id, 'folderID' => $media->parent, 'rows' => $rows ) ), 200, 'application/json', \IPS\Output::i()->httpHeaders );
|
||||
\IPS\Output::i()->sendOutput( json_encode( array( 'fileID' => $media->id, 'folderID' => $media->parent, 'rows' => $rows ) ), 200, 'application/json' );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -298,7 +305,7 @@ class _media extends \IPS\Node\Controller
|
||||
$form = new \IPS\Helpers\Form( 'form', 'upload' );
|
||||
$form->class = 'ipsForm_vertical ipsForm_noLabels';
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Upload( 'media_filename', NULL, FALSE, array( 'allowedFileTypes' => array_merge( \IPS\File::$safeFileExtensions, array( 'pdf', 'svg' ) ), 'obscure' => FALSE, 'maxFileSize' => 5, 'storageExtension' => 'cms_Media', 'storageContainer' => 'pages_media', 'multiple' => true, 'minimize' => FALSE ), NULL, NULL, NULL, 'media_filename' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Upload( 'media_filename', NULL, FALSE, array( 'allowedFileTypes' => array_merge( \IPS\File::$safeFileExtensions, array( 'pdf', 'svg' ) ), 'obscure' => FALSE, 'storageExtension' => 'cms_Media', 'storageContainer' => 'pages_media', 'multiple' => true, 'minimize' => FALSE ), NULL, NULL, NULL, 'media_filename' ) );
|
||||
|
||||
if ( ! isset( \IPS\Request::i()->media_parent ) and ! \IPS\Request::i()->media_parent )
|
||||
{
|
||||
@@ -380,7 +387,7 @@ class _media extends \IPS\Node\Controller
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->sendOutput( json_encode( array( 'count' => $count, 'folderID' => $parent, 'rows' => $rows ) ), 200, 'application/json', \IPS\Output::i()->httpHeaders );
|
||||
\IPS\Output::i()->sendOutput( json_encode( array( 'count' => $count, 'folderID' => $parent, 'rows' => $rows ) ), 200, 'application/json' );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -412,7 +419,7 @@ class _media extends \IPS\Node\Controller
|
||||
|
||||
if( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( json_encode( $rows ), 200, 'application/json', \IPS\Output::i()->httpHeaders );
|
||||
\IPS\Output::i()->sendOutput( json_encode( $rows ), 200, 'application/json' );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -453,13 +460,13 @@ class _media extends \IPS\Node\Controller
|
||||
$output['dimensions'] = $dimensions[0] . ' x ' . $dimensions[1];
|
||||
}
|
||||
|
||||
\IPS\Output::i()->sendOutput( json_encode( $output ), 200, 'application/json', \IPS\Output::i()->httpHeaders );
|
||||
\IPS\Output::i()->sendOutput( json_encode( $output ), 200, 'application/json' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return HTML for a page row
|
||||
*
|
||||
* @param array $row Row data
|
||||
* @param array $item Row data
|
||||
* @param object $url \IPS\Http\Url object
|
||||
* @return string HTML
|
||||
*/
|
||||
@@ -471,7 +478,7 @@ class _media extends \IPS\Node\Controller
|
||||
/**
|
||||
* Return HTML for a folder row
|
||||
*
|
||||
* @param array $row Row data
|
||||
* @param array $folder Row data
|
||||
* @param object $url \IPS\Http\Url object
|
||||
* @return string HTML
|
||||
*/
|
||||
@@ -484,7 +491,7 @@ class _media extends \IPS\Node\Controller
|
||||
/**
|
||||
* Fetch rows of folders/pages
|
||||
*
|
||||
* @param int $folderId Parent ID to fetch from
|
||||
* @param int $folderId Parent ID to fetch from
|
||||
*/
|
||||
public static function getRowsForTree( $folderId=0 )
|
||||
{
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
namespace IPS\cms\modules\admin\pages;
|
||||
|
||||
/* 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;
|
||||
@@ -24,6 +24,11 @@ exit;
|
||||
*/
|
||||
class _pages extends \IPS\Node\Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Node Class
|
||||
*/
|
||||
@@ -122,14 +127,6 @@ class _pages extends \IPS\Node\Controller
|
||||
FALSE
|
||||
);
|
||||
|
||||
/* Add a button for managing DB settings */
|
||||
\IPS\Output::i()->sidebar['actions']['pagessettings'] = array(
|
||||
'title' => 'cms_pages_settings',
|
||||
'icon' => 'wrench',
|
||||
'link' => \IPS\Http\Url::internal( 'app=cms&module=pages&controller=pages&do=settings' ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('cms_pages_settings') )
|
||||
);
|
||||
|
||||
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'cms', 'pages', 'page_add' ) )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['actions']['add_folder'] = array(
|
||||
@@ -150,115 +147,6 @@ class _pages extends \IPS\Node\Controller
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Page settings form
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function settings()
|
||||
{
|
||||
$url = parse_url( \IPS\Settings::i()->base_url );
|
||||
$disabled = FALSE;
|
||||
$options = array();
|
||||
$url['path'] = preg_replace( '#^/?(.+?)?/?$#', '\1', $url['path'] );
|
||||
|
||||
$disabled = ( \IPS\Settings::i()->cms_use_different_gateway or $url['path'] ) ? FALSE : TRUE;
|
||||
$dirs = explode( '/', $url['path'] );
|
||||
|
||||
if ( count( $dirs ) )
|
||||
{
|
||||
array_pop( $dirs );
|
||||
$base = $url['scheme'] . '://' . $url['host'];
|
||||
if ( isset( $url['port'] ) )
|
||||
{
|
||||
$base .= ':' .$url['port'];
|
||||
}
|
||||
|
||||
$base .= '/';
|
||||
$options[ $base ] = $base;
|
||||
foreach( $dirs as $dir )
|
||||
{
|
||||
$base .= $dir . '/';
|
||||
$options[ $base ] = $base;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $disabled )
|
||||
{
|
||||
\IPS\Member::loggedIn()->language()->words['cms_use_different_gateway_warning'] = \IPS\Member::loggedIn()->language()->addToStack('cms_pages_different_gateway_impossible');
|
||||
}
|
||||
|
||||
if ( \IPS\Settings::i()->htaccess_mod_rewrite )
|
||||
{
|
||||
\IPS\Member::loggedIn()->language()->words['cms_root_page_url_desc'] = \IPS\Member::loggedIn()->language()->addToStack('cms_root_page_url_rewrite_desc');
|
||||
}
|
||||
|
||||
$form = new \IPS\Helpers\Form( 'form', 'save' );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'cms_use_different_gateway', \IPS\Settings::i()->cms_use_different_gateway, FALSE, array( 'togglesOn' => array( 'cms_root_page_url' ), 'disabled' => $disabled ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'cms_root_page_url', \IPS\Settings::i()->cms_root_page_url, FALSE, array( 'options' => $options ), function( $val )
|
||||
{
|
||||
if ( $val and \IPS\Request::i()->cms_use_different_gateway )
|
||||
{
|
||||
if ( mb_substr( $val, -1 ) !== '/' )
|
||||
{
|
||||
$val .= '/';
|
||||
}
|
||||
|
||||
$page = \IPS\cms\Pages\Page::getDefaultPage();
|
||||
|
||||
$response = \IPS\Http\Url::external( ( \IPS\Settings::i()->htaccess_mod_rewrite ? $val . $page->full_path : $val . 'index.php?/' . $page->full_path ) )->request( NULL, NULL, FALSE )->get();
|
||||
|
||||
if ( $response->httpResponseCode != 200 and $response->httpResponseCode != 303 and ( \IPS\Settings::i()->site_online OR $response->httpResponseCode != 503 ) )
|
||||
{
|
||||
if ( \IPS\Settings::i()->htaccess_mod_rewrite )
|
||||
{
|
||||
throw new \LogicException( 'pages_different_gateway_load_error_rewrite' );
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new \LogicException( 'pages_different_gateway_load_error' );
|
||||
}
|
||||
}
|
||||
}
|
||||
}, NULL, NULL, 'cms_root_page_url' ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'cms_error_page', \IPS\Settings::i()->cms_error_page ? \IPS\Settings::i()->cms_error_page : 0, FALSE,array(
|
||||
'class' => '\IPS\cms\Pages\Page',
|
||||
'zeroVal' => 'cms_error_page_none',
|
||||
'subnodes' => true,
|
||||
'permissionCheck' => function( $node )
|
||||
{
|
||||
return $node->type == 'html';
|
||||
}
|
||||
) ) );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
$form->saveAsSettings();
|
||||
\IPS\Member::clearCreateMenu();
|
||||
|
||||
/* Clear Sidebar Caches */
|
||||
\IPS\Widget::deleteCaches();
|
||||
|
||||
/* Possible gateway choice changed and thusly menu and page_urls will change */
|
||||
if ( isset( \IPS\Data\Store::i()->pages_page_urls ) )
|
||||
{
|
||||
unset( \IPS\Data\Store::i()->pages_page_urls );
|
||||
}
|
||||
|
||||
if ( isset( \IPS\Data\Store::i()->frontNavigation ) )
|
||||
{
|
||||
unset( \IPS\Data\Store::i()->frontNavigation );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=cms&module=pages&controller=pages" ), 'saved' );
|
||||
}
|
||||
|
||||
/* Display */
|
||||
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'global', 'core', 'admin' )->block( \IPS\Member::loggedIn()->language()->addToStack('cms_pages_settings'), $form, FALSE );
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('cms_pages_settings');
|
||||
}
|
||||
|
||||
/**
|
||||
* Download .htaccess file
|
||||
*
|
||||
@@ -269,7 +157,7 @@ class _pages extends \IPS\Node\Controller
|
||||
$dir = str_replace( \IPS\CP_DIRECTORY . '/index.php', '', $_SERVER['PHP_SELF'] );
|
||||
$dirs = explode( '/', trim( $dir, '/' ) );
|
||||
|
||||
if ( count( $dirs ) )
|
||||
if ( \count( $dirs ) )
|
||||
{
|
||||
array_pop( $dirs );
|
||||
$dir = implode( '/', $dirs );
|
||||
@@ -350,6 +238,7 @@ FILE;
|
||||
{
|
||||
if ( isset( \IPS\Request::i()->id ) )
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
\IPS\cms\Pages\Page::deleteCompiled( \IPS\Request::i()->id );
|
||||
}
|
||||
|
||||
@@ -363,10 +252,23 @@ FILE;
|
||||
*/
|
||||
protected function setAsDefault()
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
\IPS\cms\Pages\Page::load( \IPS\Request::i()->id )->setAsDefault();
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=cms&module=pages&controller=pages" ), 'saved' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set as default error page
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function toggleDefaultError()
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
\IPS\Settings::i()->changeValues( array( 'cms_error_page' => \IPS\Request::i()->id ? \IPS\Request::i()->id : NULL ) );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=cms&module=pages&controller=pages" ), 'saved' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Tree Search
|
||||
*
|
||||
@@ -395,7 +297,7 @@ FILE;
|
||||
/**
|
||||
* Return HTML for a page row
|
||||
*
|
||||
* @param array $row Row data
|
||||
* @param array $page Row data
|
||||
* @param object $url \IPS\Http\Url object
|
||||
* @return string HTML
|
||||
*/
|
||||
@@ -413,7 +315,7 @@ FILE;
|
||||
/**
|
||||
* Return HTML for a folder row
|
||||
*
|
||||
* @param array $row Row data
|
||||
* @param array $folder Row data
|
||||
* @param object $url \IPS\Http\Url object
|
||||
* @return string HTML
|
||||
*/
|
||||
@@ -425,7 +327,7 @@ FILE;
|
||||
/**
|
||||
* Fetch rows of folders/pages
|
||||
*
|
||||
* @param int $folderId Parent ID to fetch from
|
||||
* @param int $folderId Parent ID to fetch from
|
||||
*/
|
||||
public static function getRowsForTree( $folderId=0 )
|
||||
{
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
namespace IPS\cms\modules\admin\pages;
|
||||
|
||||
/* 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;
|
||||
@@ -23,6 +23,11 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
*/
|
||||
class _templates extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
/**
|
||||
* @brief Has been CSRF-protected
|
||||
*/
|
||||
public static $csrfProtected = TRUE;
|
||||
|
||||
/**
|
||||
* Execute
|
||||
*
|
||||
@@ -41,6 +46,8 @@ class _templates extends \IPS\Dispatcher\Controller
|
||||
*/
|
||||
public function importInDev()
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
\IPS\cms\Theme::importInDev('database');
|
||||
\IPS\cms\Theme::importInDev('page');
|
||||
|
||||
@@ -67,7 +74,7 @@ class _templates extends \IPS\Dispatcher\Controller
|
||||
move_uploaded_file( $values['cms_templates_import'], $tempFile );
|
||||
|
||||
/* Initate a redirector */
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=cms&module=pages&controller=templates&do=importProcess' )->setQueryString( array( 'file' => $tempFile, 'key' => md5_file( $tempFile ) ) ) );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=cms&module=pages&controller=templates&do=importProcess' )->csrf()->setQueryString( array( 'file' => $tempFile, 'key' => md5_file( $tempFile ) ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -85,100 +92,198 @@ class _templates extends \IPS\Dispatcher\Controller
|
||||
*/
|
||||
public function importProcess()
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
if ( !file_exists( \IPS\Request::i()->file ) or md5_file( \IPS\Request::i()->file ) !== \IPS\Request::i()->key )
|
||||
{
|
||||
\IPS\Output::i()->error( 'generic_error', '3T285/3', 403, '' );
|
||||
}
|
||||
|
||||
/* Open XML file */
|
||||
$xml = new \IPS\Xml\XMLReader;
|
||||
$xml->open( \IPS\Request::i()->file );
|
||||
$prefix = 'm' . date('m') . '_' . date('d') . '_' . date('y') . '_';
|
||||
$templates = \IPS\cms\Theme::i()->getRawTemplates( 'cms', NULL, NULL, \IPS\cms\Theme::RETURN_ALL );
|
||||
|
||||
if ( ! @$xml->read() )
|
||||
$result = NULL;
|
||||
try
|
||||
{
|
||||
$result = \IPS\cms\Templates::importUserTemplateXml( \IPS\Request::i()->file );
|
||||
}
|
||||
catch( \Throwable $e )
|
||||
{
|
||||
@unlink( \IPS\Request::i()->file );
|
||||
\IPS\Output::i()->error( 'xml_upload_invalid', '2C163/1', 403, '' );
|
||||
}
|
||||
$xml->read();
|
||||
while ( $xml->read() )
|
||||
|
||||
/* Done */
|
||||
if ( $result instanceof \IPS\Http\Url\Internal )
|
||||
{
|
||||
if ( $xml->name === 'template' )
|
||||
\IPS\Output::i()->redirect( $result );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=cms&module=pages&controller=templates&do=manage' ), 'cms_templates_imported' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show and manage conflicts
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function conflicts()
|
||||
{
|
||||
$key = \intval( \IPS\Request::i()->key );
|
||||
$form = new \IPS\Helpers\Form( 'form', 'theme_conflict_save' );
|
||||
$conflicts = array();
|
||||
|
||||
/* If this is part of plugin/app installation, set relevant form data */
|
||||
if( \IPS\Request::i()->app OR \IPS\Request::i()->plugin )
|
||||
{
|
||||
if( \IPS\Request::i()->app )
|
||||
{
|
||||
$node = new \SimpleXMLElement( $xml->readOuterXML() );
|
||||
$attrs = array();
|
||||
$form->hiddenValues['app'] = \IPS\Request::i()->app;
|
||||
}
|
||||
elseif( \IPS\Request::i()->plugin )
|
||||
{
|
||||
$form->hiddenValues['plugin'] = \IPS\Request::i()->plugin;
|
||||
}
|
||||
|
||||
foreach( $node->attributes() as $k => $v )
|
||||
{
|
||||
$attrs[ $k ] = (string) $v;
|
||||
}
|
||||
if( \IPS\Request::i()->marketplace )
|
||||
{
|
||||
$form->hiddenValues['marketplace'] = (int) \IPS\Request::i()->marketplace;
|
||||
}
|
||||
|
||||
/* Any kids of your own? */
|
||||
foreach( $node->children() as $k => $v )
|
||||
{
|
||||
$tryJson = json_decode( $v, TRUE );
|
||||
$attrs[ $k ] = ( $tryJson ) ? $tryJson : (string) $v;
|
||||
}
|
||||
if( \IPS\Request::i()->lang )
|
||||
{
|
||||
$form->hiddenValues['lang'] = \IPS\Request::i()->lang;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $attrs['template_title'] ) and isset( $attrs['template_location'] ) and isset( $attrs['template_group'] ) )
|
||||
/* Get conflict data */
|
||||
foreach( \IPS\Db::i()->select( '*', 'cms_template_conflicts', array( 'conflict_key=?', $key ) )->setKeyField( 'conflict_id' ) as $cid => $data )
|
||||
{
|
||||
$conflicts[ $cid ] = $data;
|
||||
}
|
||||
|
||||
require_once \IPS\ROOT_PATH . "/system/3rd_party/Diff/class.Diff.php";
|
||||
|
||||
foreach( $conflicts as $cid => $data )
|
||||
{
|
||||
try
|
||||
{
|
||||
$template = \IPS\cms\Templates::load( $data['conflict_item_id'], 'template_id' );
|
||||
|
||||
if ( !\IPS\Login::compareHashes( md5( $data['conflict_content'] ), md5( $template->content ) ) )
|
||||
{
|
||||
/* Got this template? */
|
||||
if ( $attrs['template_location'] === 'database' )
|
||||
if ( mb_strlen( $data['conflict_content'] ) <= 10000 )
|
||||
{
|
||||
/* Database templates are really governed by the group as they are a collection of templates */
|
||||
if ( isset( $templates['cms'][$attrs['template_location']][$attrs['template_group']] ) )
|
||||
{
|
||||
$attrs['template_group'] = $prefix . $attrs['template_group'];
|
||||
}
|
||||
$conflicts[ $cid ]['diff'] = \Diff::toTable( \Diff::compare( $template->content, $data['conflict_content'] ) );
|
||||
$conflicts[ $cid ]['large'] = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* But post and block templates are not */
|
||||
if ( isset( $templates['cms'][$attrs['template_location']][$attrs['template_group']] ) )
|
||||
{
|
||||
$exists = FALSE;
|
||||
foreach ( $templates['cms'][$attrs['template_location']][$attrs['template_group']] as $key => $template )
|
||||
{
|
||||
if ( $template['template_title'] === $attrs['template_title'] )
|
||||
{
|
||||
$exists = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $exists )
|
||||
{
|
||||
$attrs['template_title'] = $prefix . $attrs['template_title'];
|
||||
}
|
||||
}
|
||||
$conflicts[ $cid ]['diff'] = \IPS\Theme::i()->getTemplate( 'customization' )->templateConflictLarge( $template->content, $data['conflict_content'], 'html' );
|
||||
$conflicts[ $cid ]['large'] = true;
|
||||
}
|
||||
|
||||
$obj = new \IPS\cms\Templates;
|
||||
$obj->location = $attrs['template_location'];
|
||||
$obj->group = $attrs['template_group'];
|
||||
$obj->title = $attrs['template_title'];
|
||||
$obj->params = $attrs['template_params'];
|
||||
$obj->content = $attrs['template_content'];
|
||||
$obj->original_group = $attrs['template_original_group'];
|
||||
$obj->type = 'template';
|
||||
$obj->user_created = 1;
|
||||
$obj->user_edited = 1;
|
||||
$obj->desc = '';
|
||||
$obj->save();
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'conflict_' . $data['conflict_id'], 'old', false, array('options' => array('old' => '', 'new' => '')) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
unset( $conflicts[ $cid ] );
|
||||
}
|
||||
}
|
||||
catch( \Exception $e )
|
||||
{
|
||||
unset( $conflicts[ $cid ] );
|
||||
}
|
||||
}
|
||||
|
||||
$obj->key = $obj->location . \IPS\Http\Url\Friendly::seoTitle( $obj->group ) . '_' . \IPS\Http\Url\Friendly::seoTitle( $obj->title ) . '_' . $obj->id;
|
||||
$obj->save();
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
$conflicts = array();
|
||||
$conflictIds = array();
|
||||
$templates = array();
|
||||
|
||||
foreach( $values as $k => $v )
|
||||
{
|
||||
if ( \substr( $k, 0, 9 ) == 'conflict_' )
|
||||
{
|
||||
if ( $v == 'new' )
|
||||
{
|
||||
$conflictIds[ (int) \substr( $k, 9 ) ] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$xml->next();
|
||||
if ( \count( $conflictIds ) )
|
||||
{
|
||||
/* Get conflict data */
|
||||
foreach( \IPS\Db::i()->select( '*', 'cms_template_conflicts', \IPS\Db::i()->in( 'conflict_id', array_keys( $conflictIds ) ) )->setKeyField( 'conflict_id' ) as $cid => $data )
|
||||
{
|
||||
$conflicts[ $data['conflict_item_id'] ] = $data;
|
||||
}
|
||||
}
|
||||
|
||||
if ( \count( $conflicts ) )
|
||||
{
|
||||
$templates = iterator_to_array( \IPS\Db::i()->select(
|
||||
'*',
|
||||
'cms_templates',
|
||||
array( \IPS\Db::i()->in( 'template_id', array_keys( $conflicts ) ) )
|
||||
)->setKeyField( 'template_id' ) );
|
||||
}
|
||||
|
||||
foreach( $templates as $templateid => $template )
|
||||
{
|
||||
if ( isset( $conflicts[ $template['template_id'] ] ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$templateObj = \IPS\cms\Templates::load( $template['template_id'], 'template_id' );
|
||||
$templateObj->params = $conflicts[ $template['template_id'] ]['conflict_data'];
|
||||
$templateObj->content = $conflicts[ $template['template_id'] ]['conflict_content'];
|
||||
$templateObj->user_edited = (int) $templateObj->isDifferentFromMaster();
|
||||
$templateObj->save();
|
||||
}
|
||||
catch( \Exception $e ) { }
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear out conflicts for this theme set */
|
||||
\IPS\Db::i()->delete( 'cms_template_conflicts', array('conflict_key=?', \IPS\Request::i()->key ) );
|
||||
|
||||
$lang = NULL;
|
||||
if( !empty( $values['lang'] ) )
|
||||
{
|
||||
$lang = $values['lang'] == 'updated' ? 'app_now_updated' : 'app_now_installed';
|
||||
}
|
||||
|
||||
if( !empty( $values['marketplace'] ) )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=marketplace&controller=marketplace&do=viewFile&id=' . $values['marketplace'] ), $lang );
|
||||
}
|
||||
elseif( !empty( $values['app'] ) )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=applications&controller=applications' ), $lang );
|
||||
}
|
||||
elseif( !empty( $values['plugin'] ) )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=applications&controller=plugins' ), 'plugin_now_installed' );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=cms&module=pages&controller=templates&do=manage' ), 'completed' );
|
||||
}
|
||||
|
||||
@unlink( \IPS\Request::i()->file );
|
||||
if ( \count( $conflicts ) )
|
||||
{
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'system/diff.css', 'core', 'admin' ) );
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'codemirror/codemirror.js', 'core', 'interface' ) );
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'codemirror/codemirror.css', 'core', 'interface' ) );
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'customization/themes.css', 'core', 'admin' ) );
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'admin_templates.js', 'core', 'admin' ) );
|
||||
|
||||
/* Done */
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=cms&module=pages&controller=templates&do=manage' ), 'cms_templates_imported' );
|
||||
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'templates', 'cms' ), 'templateConflict' ), $conflicts );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=cms&module=pages&controller=templates&do=manage' ), 'completed' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -188,149 +293,17 @@ class _templates extends \IPS\Dispatcher\Controller
|
||||
*/
|
||||
public function export()
|
||||
{
|
||||
$form = new \IPS\Helpers\Form( 'form', 'next' );
|
||||
$templates = array();
|
||||
|
||||
$form->addMessage( 'cms_templates_export_description', 'ipsMessage ipsMessage_information' );
|
||||
foreach( \IPS\cms\Templates::getTemplates( \IPS\cms\Templates::RETURN_DATABASE_ONLY + \IPS\cms\Templates::RETURN_ALL ) as $template )
|
||||
{
|
||||
$title = \IPS\cms\Templates::readableGroupName( $template->group );
|
||||
|
||||
if ( $template->location === 'database' )
|
||||
{
|
||||
$templates['database'][ $template->group ] = $title;
|
||||
}
|
||||
else if ( $template->location === 'block' )
|
||||
{
|
||||
$templates['block'][ $template->key ] = $title . ' > ' . $template->title;
|
||||
}
|
||||
else if ( $template->location === 'page' )
|
||||
{
|
||||
$templates['page'][ $template->key ] = $title . ' > ' . $template->title;
|
||||
}
|
||||
}
|
||||
|
||||
foreach( $templates as $location => $data )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'templates_' . $location, FALSE, FALSE, array( 'options' => $data ) ) );
|
||||
}
|
||||
$form->addButton( 'cms_templates_export_return', 'link', \IPS\Http\Url::internal( "app=cms&module=pages&controller=templates" ) );
|
||||
$form = \IPS\cms\Templates::exportForm();
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
$exportTemplates = array();
|
||||
foreach( $templates as $location => $data )
|
||||
{
|
||||
if ( isset( $values[ 'templates_' . $location ] ) and count( $values[ 'templates_' . $location ] ) )
|
||||
{
|
||||
if ( $location === 'database' )
|
||||
{
|
||||
$tmp = \IPS\cms\Theme::i()->getRawTemplates( 'cms', array('database'), array_values( $values[ 'templates_' . $location ] ) );
|
||||
$xml = \IPS\cms\Templates::exportAsXml( $values );
|
||||
|
||||
foreach( $tmp['cms'] as $loc => $data )
|
||||
{
|
||||
if ( $loc === $location )
|
||||
{
|
||||
foreach ( $data as $key => $tdata )
|
||||
{
|
||||
foreach ( $tdata as $tkey => $tkdata )
|
||||
{
|
||||
$exportTemplates['cms'][ $location ][ $key ][ $tkey ] = $tkdata;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$tmp = \IPS\cms\Theme::i()->getRawTemplates( 'cms', array( $location ), NULL, \IPS\cms\Theme::RETURN_DATABASE_ONLY + \IPS\cms\Theme::RETURN_ALL );
|
||||
|
||||
foreach( $tmp['cms'] as $loc => $data )
|
||||
{
|
||||
if ( $loc === $location )
|
||||
{
|
||||
foreach( $data as $key => $tdata )
|
||||
{
|
||||
foreach( $tdata as $tkey => $tkdata )
|
||||
{
|
||||
if ( in_array( $tkey, $values[ 'templates_' . $location ] ) )
|
||||
{
|
||||
$exportTemplates['cms'][ $location ][ $key ][ $tkey ] = $tkdata;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( count( $exportTemplates ) )
|
||||
{
|
||||
/* Init */
|
||||
$xml = new \XMLWriter;
|
||||
$xml->openMemory();
|
||||
$xml->setIndent( TRUE );
|
||||
$xml->startDocument( '1.0', 'UTF-8' );
|
||||
|
||||
/* Root tag */
|
||||
$xml->startElement('templates');
|
||||
|
||||
foreach ( $exportTemplates as $app => $location )
|
||||
{
|
||||
foreach ( $location as $key => $data )
|
||||
{
|
||||
foreach ( $data as $group => $template )
|
||||
{
|
||||
foreach( $template as $key => $templateData )
|
||||
{
|
||||
/* Initiate the <template> tag */
|
||||
$xml->startElement( 'template' );
|
||||
|
||||
foreach ( $templateData as $k => $v )
|
||||
{
|
||||
if ( ! in_array( \substr( $k, 9 ), array( 'content', 'params' ) ) )
|
||||
{
|
||||
$xml->startAttribute( $k );
|
||||
$xml->text( $v );
|
||||
$xml->endAttribute();
|
||||
}
|
||||
}
|
||||
|
||||
/* Write (potential) HTML fields */
|
||||
foreach( array( 'template_params', 'template_content' ) as $field )
|
||||
{
|
||||
if ( isset( $templateData[ $field ] ) )
|
||||
{
|
||||
$xml->startElement( $field );
|
||||
if ( preg_match( '/<|>|&/', $templateData[ $field ] ) )
|
||||
{
|
||||
$xml->writeCData( str_replace( ']]>', ']]]]><![CDATA[>', $templateData[ $field ] ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$xml->text( $templateData[ $field ] );
|
||||
}
|
||||
$xml->endElement();
|
||||
}
|
||||
}
|
||||
|
||||
/* Close the <template> tag */
|
||||
$xml->endElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Finish */
|
||||
$xml->endDocument();
|
||||
|
||||
\IPS\Output::i()->sendOutput( $xml->outputMemory(), 200, 'application/xml', array( 'Content-Disposition' => \IPS\Output::getContentDisposition( 'attachment', "pages_templates.xml" ) ) );
|
||||
}
|
||||
else
|
||||
if( $xml === NULL )
|
||||
{
|
||||
\IPS\Output::i()->error( 'cms_no_templates_selected', '1T285/1', 403, '' );
|
||||
}
|
||||
\IPS\Output::i()->sendOutput( $xml->outputMemory(), 200, 'application/xml', array( 'Content-Disposition' => \IPS\Output::getContentDisposition( 'attachment', "pages_templates.xml" ) ) );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->breadcrumb[] = array( \IPS\Http\Url::internal( "app=cms&module=pages&controller=templates" ), \IPS\Member::loggedIn()->language()->addToStack( 'menu__cms_pages_templates' ) );
|
||||
@@ -430,7 +403,7 @@ class _templates extends \IPS\Dispatcher\Controller
|
||||
\IPS\Output::i()->sidebar['actions']['add'] = array(
|
||||
'icon' => 'cog',
|
||||
'title' => 'content_import_dev_templates',
|
||||
'link' => \IPS\Http\Url::internal( "app=cms&module=pages&controller=templates&do=importInDev" ),
|
||||
'link' => \IPS\Http\Url::internal( "app=cms&module=pages&controller=templates&do=importInDev" )->csrf(),
|
||||
'data' => array()
|
||||
);
|
||||
}
|
||||
@@ -523,10 +496,21 @@ class _templates extends \IPS\Dispatcher\Controller
|
||||
/* PHP Keywords cannot be used as template names - so make sure the full template name is not in the list */
|
||||
$keywords = array( 'abstract', 'and', 'array', 'as', 'break', 'callable', 'case', 'catch', 'class', 'clone', 'const', 'continue', 'declare', 'default', 'die', 'do', 'echo', 'else', 'elseif', 'empty', 'enddeclare', 'endfor', 'endforeach', 'endif', 'endswitch', 'endwhile', 'eval', 'exit', 'extends', 'final', 'for', 'foreach', 'function', 'global', 'goto', 'if', 'implements', 'include', 'include_once', 'instanceof', 'insteadof', 'interface', 'isset', 'list', 'namespace', 'new', 'or', 'print', 'private', 'protected', 'public', 'require', 'require_once', 'return', 'static', 'switch', 'throw', 'trait', 'try', 'unset', 'use', 'var', 'while', 'xor' );
|
||||
|
||||
if ( in_array( $val, $keywords ) )
|
||||
if ( \in_array( $val, $keywords ) )
|
||||
{
|
||||
throw new \DomainException( \IPS\Member::loggedIn()->language()->addToStack( 'template_reserved_word', FALSE, array( 'htmlsprintf' => array( \IPS\Member::loggedIn()->language()->formatList( $keywords ) ) ) ) );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$count = \IPS\Db::i()->select( 'COUNT(*)', 'cms_templates', array( "LOWER(template_title)=?", mb_strtolower( str_replace( ' ', '_', $val ) ) ) )->first();
|
||||
|
||||
if ( $count )
|
||||
{
|
||||
throw new \DomainException( 'cms_template_title_exists' );
|
||||
}
|
||||
}
|
||||
catch( \UnderflowException $e ) {}
|
||||
} ) );
|
||||
|
||||
/* Very specific */
|
||||
@@ -558,7 +542,7 @@ class _templates extends \IPS\Dispatcher\Controller
|
||||
foreach ( \IPS\Db::i()->select( "*", 'core_widgets', array( 'embeddable=1') ) as $widget )
|
||||
{
|
||||
/* Skip disabled applications */
|
||||
if ( !in_array( $widget['app'], array_keys( \IPS\Application::enabledApplications() ) ) )
|
||||
if ( !\in_array( $widget['app'], array_keys( \IPS\Application::enabledApplications() ) ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -609,7 +593,7 @@ class _templates extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! count( $groups ) )
|
||||
if ( ! \count( $groups ) )
|
||||
{
|
||||
$groups[ $type ] = \IPS\cms\Templates::readableGroupName( $type );
|
||||
}
|
||||
@@ -621,7 +605,18 @@ class _templates extends \IPS\Dispatcher\Controller
|
||||
'new' => array( 'group_new' ) )
|
||||
) ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'template_group_new', NULL, FALSE, array( 'regex' => '/^([a-z_][a-z0-9_]+?)?$/' ), NULL, NULL, NULL, 'group_new' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'template_group_new', NULL, FALSE, array( 'regex' => '/^([a-z_][a-z0-9_]+?)?$/' ), function( $val ) {
|
||||
try
|
||||
{
|
||||
$count = \IPS\Db::i()->select( 'COUNT(*)', 'cms_templates', array( "LOWER(template_group)=?", mb_strtolower( str_replace( ' ', '_', $val ) ) ) )->first();
|
||||
|
||||
if ( $count )
|
||||
{
|
||||
throw new \DomainException( 'cms_template_group_exists' );
|
||||
}
|
||||
}
|
||||
catch( \UnderflowException $e ) {}
|
||||
}, NULL, NULL, 'group_new' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'template_group_existing', NULL, FALSE, array( 'options' => $groups ), NULL, NULL, NULL, 'group_existing' ) );
|
||||
}
|
||||
|
||||
@@ -779,7 +774,7 @@ class _templates extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=cms&module=pages&controller=templates' ), 'saved' );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=cms&module=pages&controller=templates' )->setQueryString( ['id' => $newTemplate->id, 't_location' => $newTemplate->location, 't_type' => $type ] ), 'saved' );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -846,6 +841,27 @@ class _templates extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a difference report for an individual template file
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function diffTemplate()
|
||||
{
|
||||
$customVersion = \IPS\Db::i()->select( '*', 'cms_templates', array( 'template_id=?', (int) \IPS\Request::i()->t_item_id ) )->first();
|
||||
|
||||
try
|
||||
{
|
||||
$original = \IPS\Db::i()->select( 'template_content', 'cms_templates', array( 'template_location=? and template_group=? and template_title=? and template_master=1', $customVersion['template_location'], $customVersion['template_original_group'], $customVersion['template_title'] ) )->first();
|
||||
}
|
||||
catch( \UnderflowException $e )
|
||||
{
|
||||
$original = FALSE;
|
||||
}
|
||||
|
||||
\IPS\Output::i()->json( $original );
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a template
|
||||
*
|
||||
@@ -853,6 +869,8 @@ class _templates extends \IPS\Dispatcher\Controller
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
$key = \IPS\Request::i()->t_key;
|
||||
|
||||
$contentKey = 'editor_' . $key;
|
||||
@@ -864,12 +882,33 @@ class _templates extends \IPS\Dispatcher\Controller
|
||||
try
|
||||
{
|
||||
$obj = \IPS\cms\Templates::load( $key );
|
||||
|
||||
$obj->location = \IPS\Request::i()->t_location;
|
||||
$obj->group = empty( \IPS\Request::i()->t_group ) ? null : \IPS\Request::i()->t_group;
|
||||
$obj->title = \IPS\Request::i()->t_name;
|
||||
$obj->params = $variables;
|
||||
$obj->content = $content;
|
||||
|
||||
if ( $obj->master )
|
||||
{
|
||||
/* Do not edit a master bit directly, but overload it */
|
||||
$clone = new \IPS\cms\Templates;
|
||||
$clone->key = $obj->key;
|
||||
$clone->title = \IPS\Request::i()->t_name;
|
||||
$clone->content = $content;
|
||||
$clone->location = \IPS\Request::i()->t_location;
|
||||
$clone->group = empty( \IPS\Request::i()->t_group ) ? null : \IPS\Request::i()->t_group;
|
||||
$clone->params = $variables;
|
||||
$clone->container = $obj->container;
|
||||
$clone->position = $obj->position;
|
||||
$clone->user_edited = 1;
|
||||
$clone->master = 0;
|
||||
$clone->save();
|
||||
}
|
||||
else
|
||||
{
|
||||
$obj->location = \IPS\Request::i()->t_location;
|
||||
$obj->group = empty( \IPS\Request::i()->t_group ) ? null : \IPS\Request::i()->t_group;
|
||||
$obj->title = \IPS\Request::i()->t_name;
|
||||
$obj->params = $variables;
|
||||
$obj->content = $content;
|
||||
$obj->user_edited = 1;
|
||||
}
|
||||
|
||||
if( $description )
|
||||
{
|
||||
$obj->description = $description;
|
||||
@@ -935,7 +974,7 @@ class _templates extends \IPS\Dispatcher\Controller
|
||||
$databases[ $database['database_id'] ] = \IPS\cms\Databases::constructFromData( $database );
|
||||
}
|
||||
|
||||
if ( count( $databases ) )
|
||||
if ( \count( $databases ) )
|
||||
{
|
||||
$names = array();
|
||||
foreach( $databases as $db )
|
||||
@@ -946,8 +985,25 @@ class _templates extends \IPS\Dispatcher\Controller
|
||||
$form->addMessage( \IPS\Member::loggedIn()->language()->addToStack( 'cms_database_template_used_in', NULL, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->formatList( $names ) ) ) ), 'ipsMessage ipsMessage_info' );
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'cms_database_group_name', \IPS\cms\Templates::readableGroupName( \IPS\Request::i()->group ), NULL, array( 'regex' => '/^([A-Z_][A-Z0-9_\.\s]+?)$/i' ) ) );
|
||||
$form->addButton( "delete", "link", \IPS\Http\Url::internal( 'app=cms&module=pages&controller=templates&do=deleteTemplateGroup&group=' . \IPS\Request::i()->group . '&t_location=' . \IPS\Request::i()->t_location ), 'ipsButton ipsButton_negative', array( 'data-confirm' => 'true' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'cms_database_group_name', \IPS\cms\Templates::readableGroupName( \IPS\Request::i()->group ), NULL, array( 'regex' => '/^([A-Z_][A-Z0-9_\.\s]+?)$/i' ), function( $val ) {
|
||||
/* PHP Keywords cannot be used as template names - so make sure the full template name is not in the list */
|
||||
$keywords = array( 'abstract', 'and', 'array', 'as', 'break', 'callable', 'case', 'catch', 'class', 'clone', 'const', 'continue', 'declare', 'default', 'die', 'do', 'echo', 'else', 'elseif', 'empty', 'enddeclare', 'endfor', 'endforeach', 'endif', 'endswitch', 'endwhile', 'eval', 'exit', 'extends', 'final', 'for', 'foreach', 'function', 'global', 'goto', 'if', 'implements', 'include', 'include_once', 'instanceof', 'insteadof', 'interface', 'isset', 'list', 'namespace', 'new', 'or', 'print', 'private', 'protected', 'public', 'require', 'require_once', 'return', 'static', 'switch', 'throw', 'trait', 'try', 'unset', 'use', 'var', 'while', 'xor' );
|
||||
|
||||
if ( \in_array( $val, $keywords ) )
|
||||
{
|
||||
throw new \DomainException( \IPS\Member::loggedIn()->language()->addToStack( 'template_reserved_word', FALSE, array( 'htmlsprintf' => array( \IPS\Member::loggedIn()->language()->formatList( $keywords ) ) ) ) );
|
||||
}
|
||||
|
||||
if ( mb_strtolower( str_replace( ' ', '_', $val ) ) != mb_strtolower( str_replace( ' ', '_', \IPS\Request::i()->group ) ) )
|
||||
{
|
||||
$count = \IPS\Db::i()->select( 'COUNT(*)', 'cms_templates', array( "LOWER(template_group)=?", mb_strtolower( str_replace( ' ', '_', $val ) ) ) )->first();
|
||||
if ( $count )
|
||||
{
|
||||
throw new \DomainException( 'cms_template_group_exists' );
|
||||
}
|
||||
}
|
||||
} ) );
|
||||
$form->addButton( "delete", "link", \IPS\Http\Url::internal( 'app=cms&module=pages&controller=templates&do=deleteTemplateGroup&group=' . \IPS\Request::i()->group . '&t_location=' . \IPS\Request::i()->t_location )->csrf(), 'ipsButton ipsButton_negative', array( 'data-confirm' => 'true' ) );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
@@ -983,6 +1039,8 @@ class _templates extends \IPS\Dispatcher\Controller
|
||||
*/
|
||||
protected function findAndUpdateTemplates( $new, $old )
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
foreach( \IPS\Db::i()->select( '*', 'cms_templates', array( 'template_content LIKE ?', '%' . $old . '%' ) ) as $template )
|
||||
{
|
||||
/* Make sure template tags call the correct group */
|
||||
@@ -1025,6 +1083,8 @@ class _templates extends \IPS\Dispatcher\Controller
|
||||
*/
|
||||
public function deleteTemplateGroup()
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
foreach( \IPS\cms\Templates::$databaseDefaults as $field => $template )
|
||||
{
|
||||
\IPS\Db::i()->update( 'cms_databases', array( 'database_template_' . $field => $template ), array( 'database_template_' . $field . ' =?', \IPS\Request::i()->group ) );
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
namespace IPS\cms\modules\front\database;
|
||||
|
||||
/* 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,7 +36,7 @@ class _ajax extends \IPS\Dispatcher\Controller
|
||||
/**
|
||||
* Find Record
|
||||
*
|
||||
* @retun void
|
||||
* @return void
|
||||
*/
|
||||
public function findRecord()
|
||||
{
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
namespace IPS\cms\modules\front\database;
|
||||
|
||||
/* 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;
|
||||
@@ -94,24 +94,85 @@ class _category extends \IPS\cms\Databases\Controller
|
||||
}
|
||||
|
||||
$RecordsClass = $category::$contentItemClass;
|
||||
|
||||
|
||||
/* AdvancedSearch can wipe out the checked box as it is looking for _checkbox. Note to self in 4.5, rewrite the filter widget to avoid using advancedSearch :/ */
|
||||
if ( ! isset( \IPS\Request::i()->cms_record_i_started_checkbox ) and isset( \IPS\Request::i()->cms_record_i_started ) and \IPS\Request::i()->cms_record_i_started )
|
||||
{
|
||||
\IPS\Request::i()->cms_record_i_started_checkbox = \IPS\Request::i()->cms_record_i_started;
|
||||
}
|
||||
|
||||
/* we need this language later (and in Widgets\DatabaseFilters which is executed just before output) */
|
||||
\IPS\Member::loggedIn()->language()->words['cms_record_i_started'] = \IPS\Member::loggedIn()->language()->addToStack( 'cms_record_i_started_sprintf', NULL, array( 'sprintf' => $database->recordWord() ) );
|
||||
|
||||
/* Check cookie */
|
||||
$where = array();
|
||||
$cookie = $category->getFilterCookie();
|
||||
|
||||
|
||||
if ( $cookie !== NULL )
|
||||
{
|
||||
foreach( $cookie as $f => $v )
|
||||
{
|
||||
if ( $f == 'cms_record_i_started' and \IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
$where[] = 'cms_custom_database_' . $database->id . '.member_id=' . \IPS\Member::loggedIn()->member_id;
|
||||
|
||||
/* FilterMessage template only accepts \IPS\cms\Fields */
|
||||
$field = new \IPS\cms\Fields;
|
||||
$field->id = 'cms_record_i_started';
|
||||
|
||||
\IPS\Member::loggedIn()->language()->words['content_field_cms_record_i_started'] = \IPS\Member::loggedIn()->language()->addToStack( 'cms_record_i_started_sprintf', NULL, array( 'sprintf' => $database->recordWord() ) );
|
||||
|
||||
static::$activeFilters['cms_record_i_started'] = array( 'field' => $field, 'value' => \IPS\Member::loggedIn()->language()->addToStack('content_field_cms_record_i_started_on') );
|
||||
continue;
|
||||
}
|
||||
|
||||
$k = 'content_field_' . $f;
|
||||
|
||||
$displayValue = $customFields[ $f ]->displayValue( $v );
|
||||
$concat = ',';
|
||||
|
||||
if ( $customFields[ $f ]->type === 'Member' )
|
||||
{
|
||||
if ( ! empty( $v ) )
|
||||
{
|
||||
$newValue = array();
|
||||
$newDisplayValue = array();
|
||||
$concat = '\n';
|
||||
|
||||
if ( \is_array( $v ) )
|
||||
{
|
||||
foreach( $v as $m )
|
||||
{
|
||||
$member = \IPS\Member::load( $m );
|
||||
$newValue[] = $member->member_id;
|
||||
$newDisplayValue[] = $member->name;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$member = \IPS\Member::load( $v );
|
||||
$newValue[] = $member->member_id;
|
||||
$newDisplayValue[] = $member->name;
|
||||
}
|
||||
|
||||
$displayValue = implode( ', ', $newDisplayValue );
|
||||
$v = $newValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The content_field_x can be an empty array from the member form */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $customFields[ $f ] ) and !isset( \IPS\Request::i()->$k ) and $v !== '___any___' )
|
||||
{
|
||||
if ( is_array( $v ) )
|
||||
if ( \is_array( $v ) )
|
||||
{
|
||||
if ( array_key_exists( 'start', $v ) or array_key_exists( 'end', $v ) )
|
||||
{
|
||||
$start = ( $v['start'] instanceof \IPS\DateTime ) ? $v['start']->getTimestamp() : intval( $v['start'] );
|
||||
$end = ( $v['end'] instanceof \IPS\DateTime ) ? $v['end']->getTimestamp() : intval( $v['end'] );
|
||||
$start = ( $v['start'] instanceof \IPS\DateTime ) ? $v['start']->getTimestamp() : \intval( $v['start'] );
|
||||
$end = ( $v['end'] instanceof \IPS\DateTime ) ? $v['end']->getTimestamp() : \intval( $v['end'] );
|
||||
|
||||
if ( $start or $end )
|
||||
{
|
||||
@@ -125,16 +186,16 @@ class _category extends \IPS\cms\Databases\Controller
|
||||
{
|
||||
if ( $val === 0 or ! empty( $val ) )
|
||||
{
|
||||
$like[] = "CONCAT( ',', " . mb_substr( $k, 8 ) . ", ',') LIKE '%," . \IPS\Db::i()->real_escape_string( $val ) . ",%'";
|
||||
$like[] = "CONCAT( '{$concat}', " . mb_substr( $k, 8 ) . ", '{$concat}') LIKE '%{$concat}" . \IPS\Db::i()->real_escape_string( $val ) . "{$concat}%'";
|
||||
}
|
||||
}
|
||||
|
||||
$where[] = array( '( ' . \IPS\Db::i()->in( mb_substr( $k, 8 ), $v ) . ( count( $like ) ? " OR (" . implode( ' OR ', $like ) . ') )' : ')' ) );
|
||||
$where[] = array( '( ' . \IPS\Db::i()->in( mb_substr( $k, 8 ), $v ) . ( \count( $like ) ? " OR (" . implode( ' OR ', $like ) . ') )' : ')' ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( is_bool( $v ) )
|
||||
if ( \is_bool( $v ) )
|
||||
{
|
||||
/* YesNo fields are false or true */
|
||||
if ( $v === false )
|
||||
@@ -159,368 +220,471 @@ class _category extends \IPS\cms\Databases\Controller
|
||||
}
|
||||
}
|
||||
|
||||
static::$activeFilters[ $f ] = array( 'field' => $customFields[ $f ], 'value' => $customFields[ $f ]->displayValue( $v ) );
|
||||
static::$activeFilters[ $f ] = array( 'field' => $customFields[ $f ], 'value' => $displayValue );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! count( $where ) )
|
||||
else
|
||||
{
|
||||
$where = NULL;
|
||||
}
|
||||
|
||||
$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 ? $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 ) ) ) ) );
|
||||
|
||||
/* 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 == $RecordsClass::$databaseTable . '.' . 'field_' . $id OR $table->sortBy == 'field_' . $id )
|
||||
foreach( $customFields as $field )
|
||||
{
|
||||
if ( $obj->type == 'Number' )
|
||||
if ( $field->type === 'Member' )
|
||||
{
|
||||
$table->sortOptions[ $table->sortBy ] = 'LENGTH(`field_' . $id . '`) ' . $table->sortDirection . ',`field_' . $id . '`';
|
||||
break;
|
||||
}
|
||||
elseif( $obj->type == 'Date' )
|
||||
{
|
||||
$table->sortOptions[ $table->sortBy ] = 'CAST(`field_' . $id . '` AS UNSIGNED)';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure table doesn't add breadcrumbs if we're not using categories */
|
||||
if ( ! $database->use_categories )
|
||||
{
|
||||
\IPS\Output::i()->breadcrumb = $breadcrumbs;
|
||||
}
|
||||
|
||||
/* Custom Search */
|
||||
$filterOptions = array(
|
||||
'all' => 'content_all_records',
|
||||
'open' => 'content_open_records',
|
||||
'locked' => 'content_locked_records',
|
||||
);
|
||||
$timeFrameOptions = array(
|
||||
'show_all' => 'show_all',
|
||||
'today' => 'today',
|
||||
'last_5_days' => 'last_5_days',
|
||||
'last_7_days' => 'last_7_days',
|
||||
'last_10_days' => 'last_10_days',
|
||||
'last_15_days' => 'last_15_days',
|
||||
'last_20_days' => 'last_20_days',
|
||||
'last_25_days' => 'last_25_days',
|
||||
'last_30_days' => 'last_30_days',
|
||||
'last_60_days' => 'last_60_days',
|
||||
'last_90_days' => 'last_90_days',
|
||||
);
|
||||
|
||||
if ( \IPS\Member::loggedIn()->member_id AND \IPS\Member::loggedIn()->last_visit)
|
||||
{
|
||||
$timeFrameOptions['since_last_visit'] = \IPS\Member::loggedIn()->language()->addToStack('since_last_visit', FALSE, array( 'sprintf' => array( \IPS\DateTime::ts( \IPS\Member::loggedIn()->last_visit ) ) ) );
|
||||
}
|
||||
|
||||
$sortBy = array(
|
||||
'record_updated' => 'content_record_last_updated',
|
||||
'record_comments' => 'content_record_comments',
|
||||
'record_views' => 'content_record_views',
|
||||
'field_' . $database->field_title => 'content_record_title',
|
||||
'record_publish_date' => 'content_record_publish_date'
|
||||
);
|
||||
|
||||
/* Ensure we have all sort options available */
|
||||
$table->sortOptions = array_unique( array_merge( $table->sortOptions, array_combine( array_keys( $sortBy ), array_keys( $sortBy ) ) ) );
|
||||
|
||||
/* To avoid confusion, label 'updated' as 'Recently Updated' as last comment */
|
||||
\IPS\Member::loggedIn()->language()->words[ $table->langPrefix . 'sort_updated' ] = \IPS\Member::loggedIn()->language()->addToStack('content_record_last_comment');
|
||||
|
||||
if ( !isset( $sortBy[ $database->field_sort ] ) )
|
||||
{
|
||||
switch ( $database->field_sort )
|
||||
{
|
||||
case 'primary_id_field':
|
||||
$sortBy[ $database->field_sort ] = 'database_field__id';
|
||||
$table->sortOptions['database_field__id'] = $database->field_sort;
|
||||
\IPS\Member::loggedIn()->language()->words['sort_database_field__id'] = \IPS\Member::loggedIn()->language()->addToStack('database_field__id');
|
||||
break;
|
||||
case 'member_id':
|
||||
$sortBy[ $database->field_sort ] = 'database_field__member';
|
||||
$table->sortOptions['database_field__member'] = $database->field_sort;
|
||||
\IPS\Member::loggedIn()->language()->words['sort_database_field__member'] = \IPS\Member::loggedIn()->language()->addToStack('database_field__member');
|
||||
break;
|
||||
case 'record_rating':
|
||||
$sortBy[ $database->field_sort ] = 'database_field__rating';
|
||||
$table->sortOptions['rating'] = $database->field_sort;
|
||||
\IPS\Member::loggedIn()->language()->words['sort_database_field__rating'] = \IPS\Member::loggedIn()->language()->addToStack('database_field__rating');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !$database->options['comments'] )
|
||||
{
|
||||
unset ( $sortBy['record_last_comment'] );
|
||||
unset ( $sortBy['record_comments'] );
|
||||
unset ( $table->sortOptions['record_last_comment'] );
|
||||
unset ( $table->sortOptions['record_comments'] );
|
||||
unset ( $table->sortOptions['last_comment'] );
|
||||
unset ( $table->sortOptions['num_comments'] );
|
||||
}
|
||||
|
||||
if ( !$database->options['reviews'] )
|
||||
{
|
||||
unset ( $table->sortOptions['num_reviews'] );
|
||||
unset( $table->sortOptions['rating'] );
|
||||
}
|
||||
|
||||
/* If the sort field isn't one of the above, best add it */
|
||||
if ( mb_substr( $database->field_sort, 0, 6 ) === 'field_' )
|
||||
{
|
||||
if ( $database->field_title !== mb_substr( $database->field_sort, 6 ) )
|
||||
{
|
||||
$sortBy[ $database->field_sort ] = \IPS\Member::loggedIn()->language()->addToStack( 'content_field_' . mb_substr( $database->field_sort, 6 ) );
|
||||
$table->sortOptions[ $database->field_sort ] = $database->field_sort;
|
||||
}
|
||||
}
|
||||
|
||||
$table->advancedSearch = array(
|
||||
'record_type' => array( \IPS\Helpers\Table\SEARCH_SELECT, array( 'options' => $filterOptions ) ),
|
||||
'sort_by' => array( \IPS\Helpers\Table\SEARCH_SELECT, array( 'options' => $sortBy ) ),
|
||||
'sort_direction' => array( \IPS\Helpers\Table\SEARCH_SELECT, array( 'options' => array(
|
||||
'asc' => 'asc',
|
||||
'desc' => 'desc',
|
||||
) )
|
||||
),
|
||||
'time_frame' => array( \IPS\Helpers\Table\SEARCH_SELECT, array( 'options' => $timeFrameOptions ) ),
|
||||
);
|
||||
|
||||
foreach( $customFields as $obj )
|
||||
{
|
||||
if ( $obj->filter )
|
||||
{
|
||||
\IPS\Member::loggedIn()->language()->words['content_field_' . $obj->id ] = $obj->_title;
|
||||
if ( in_array( $obj->type, array( 'Date', 'DateRange' ) ) )
|
||||
{
|
||||
$table->advancedSearch[ 'content_field_' . $obj->id ] = array( \IPS\Helpers\Table\SEARCH_DATE_RANGE, array( 'noDefault' => true ) );
|
||||
}
|
||||
else if ( $obj->type == 'Number' )
|
||||
{
|
||||
$table->advancedSearch[ 'content_field_' . $obj->id ] = array( \IPS\Helpers\Table\SEARCH_NUMERIC_TEXT, array( 'noDefault' => true ) );
|
||||
}
|
||||
else if ( $obj->type == 'YesNo' )
|
||||
{
|
||||
$table->advancedSearch[ 'content_field_' . $obj->id ] = array( \IPS\Helpers\Table\SEARCH_BOOL, array( 'noDefault' => true ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$table->advancedSearch[ 'content_field_' . $obj->id ] = array( \IPS\Helpers\Table\SEARCH_SELECT, array( 'options' => $obj->extra, 'multiple' => TRUE, 'noDefault' => true ) );
|
||||
}
|
||||
|
||||
$table->advancedSearch['sort_by'][1]['options']['field_' . $obj->id ] = 'content_field_' . $obj->id;
|
||||
}
|
||||
|
||||
if ( in_array( $obj->type, array( 'Date', 'DateRange' ) ) )
|
||||
{
|
||||
$table->sortOptions[ 'field_' . $obj->id ] = 'CAST(`field_' . $obj->id . '` AS UNSIGNED)';
|
||||
}
|
||||
else if ( $obj->type == 'Number' )
|
||||
{
|
||||
$table->sortOptions[ 'field_' . $obj->id ] = 'LENGTH(`field_' . $obj->id . '`) ' . $table->sortDirection . ',`field_' . $obj->id . '`';
|
||||
}
|
||||
else
|
||||
{
|
||||
$table->sortOptions[ 'field_' . $obj->id ] = isset( $table->sortOptions[ 'field_' . $obj->id ] ) ? $table->sortOptions[ 'field_' . $obj->id ] : 'field_' . $obj->id;
|
||||
}
|
||||
}
|
||||
|
||||
$table->advancedSearchCallback = function( $table, $values ) use ( $database, $sortBy, $customFields )
|
||||
{
|
||||
/* Type */
|
||||
foreach( $values as $k => $v )
|
||||
{
|
||||
if ( mb_substr( $k, 0, 14 ) === 'content_field_' )
|
||||
{
|
||||
if ( is_array( $v ) )
|
||||
$requestField = 'content_field_' . $field->id;
|
||||
$didWeJustHitSubmit = $requestField . '_original';
|
||||
$names = NULL;
|
||||
|
||||
/* We need to homogenize data, we store IDs, but the Form helper needs objects or names */
|
||||
if ( isset( \IPS\Request::i()->$requestField ) and ! isset( \IPS\Request::i()->$didWeJustHitSubmit ) )
|
||||
{
|
||||
if ( array_key_exists( 'start', $v ) or array_key_exists( 'end', $v ) )
|
||||
/* The URL alwyas uses IDs, so map these to names */
|
||||
$names = array_map( function( $id )
|
||||
{
|
||||
$start = ( $v['start'] instanceof \IPS\DateTime ) ? $v['start']->getTimestamp() : intval( $v['start'] );
|
||||
$end = ( $v['end'] instanceof \IPS\DateTime ) ? $v['end']->getTimestamp() : intval( $v['end'] );
|
||||
|
||||
if ( $start or $end )
|
||||
{
|
||||
$table->where[] = array( '( ' . mb_substr( $k, 8 ) . ' BETWEEN ' . $start . ' AND ' . $end . ' )' );
|
||||
}
|
||||
}
|
||||
else
|
||||
return \IPS\Member::load( $id )->name;
|
||||
}, ( \is_array( \IPS\Request::i()->$requestField ) ? \IPS\Request::i()->$requestField : array( \IPS\Request::i()->$requestField ) ) );
|
||||
}
|
||||
else if ( isset( \IPS\Request::i()->$requestField ) )
|
||||
{
|
||||
/* The names are foo\nbar so already names */
|
||||
$names = explode( "\n", \IPS\Request::i()->$requestField );
|
||||
}
|
||||
|
||||
if ( $names !== NULL )
|
||||
{
|
||||
\IPS\Request::i()->$requestField = $names;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ( $category->hasChildren() AND $category->show_records ) OR ! $category->hasChildren() )
|
||||
{
|
||||
if ( ! \count( $where ) )
|
||||
{
|
||||
$where = NULL;
|
||||
}
|
||||
|
||||
$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 ? $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 ) ) ) ) );
|
||||
|
||||
/* 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 == $RecordsClass::$databaseTable . '.' . 'field_' . $id OR $table->sortBy == 'field_' . $id )
|
||||
{
|
||||
if ( $obj->type == 'Number' )
|
||||
{
|
||||
$table->sortOptions[ $table->sortBy ] = 'LENGTH(`field_' . $id . '`) ' . $table->sortDirection . ',`field_' . $id . '`';
|
||||
break;
|
||||
}
|
||||
elseif( $obj->type == 'Date' )
|
||||
{
|
||||
$table->sortOptions[ $table->sortBy ] = 'CAST(`field_' . $id . '` AS UNSIGNED)';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure table doesn't add breadcrumbs if we're not using categories */
|
||||
if ( ! $database->use_categories )
|
||||
{
|
||||
\IPS\Output::i()->breadcrumb = $breadcrumbs;
|
||||
}
|
||||
|
||||
/* Custom Search */
|
||||
$filterOptions = array(
|
||||
'all' => 'content_all_records',
|
||||
'open' => 'content_open_records',
|
||||
'locked' => 'content_locked_records',
|
||||
);
|
||||
$timeFrameOptions = array(
|
||||
'show_all' => 'show_all',
|
||||
'today' => 'today',
|
||||
'last_5_days' => 'last_5_days',
|
||||
'last_7_days' => 'last_7_days',
|
||||
'last_10_days' => 'last_10_days',
|
||||
'last_15_days' => 'last_15_days',
|
||||
'last_20_days' => 'last_20_days',
|
||||
'last_25_days' => 'last_25_days',
|
||||
'last_30_days' => 'last_30_days',
|
||||
'last_60_days' => 'last_60_days',
|
||||
'last_90_days' => 'last_90_days',
|
||||
);
|
||||
|
||||
if ( \IPS\Member::loggedIn()->member_id AND \IPS\Member::loggedIn()->last_visit )
|
||||
{
|
||||
$timeFrameOptions['since_last_visit'] = \IPS\Member::loggedIn()->language()->addToStack('since_last_visit', FALSE, array( 'sprintf' => array( \IPS\DateTime::ts( \IPS\Member::loggedIn()->last_visit ) ) ) );
|
||||
}
|
||||
|
||||
$sortBy = array(
|
||||
'record_updated' => 'content_record_last_updated',
|
||||
'record_comments' => 'content_record_comments',
|
||||
'record_views' => 'content_record_views',
|
||||
'field_' . $database->field_title => 'content_record_title',
|
||||
'record_publish_date' => 'content_record_publish_date'
|
||||
);
|
||||
|
||||
/* Ensure we have all sort options available */
|
||||
$table->sortOptions = array_unique( array_merge( $table->sortOptions, array_combine( array_keys( $sortBy ), array_keys( $sortBy ) ) ) );
|
||||
|
||||
/* To avoid confusion, label 'updated' as 'Recently Updated' as last comment */
|
||||
\IPS\Member::loggedIn()->language()->words[ $table->langPrefix . 'sort_updated' ] = \IPS\Member::loggedIn()->language()->addToStack('content_record_last_comment');
|
||||
|
||||
if ( !isset( $sortBy[ $database->field_sort ] ) )
|
||||
{
|
||||
switch ( $database->field_sort )
|
||||
{
|
||||
case 'primary_id_field':
|
||||
$sortBy[ $database->field_sort ] = 'database_field__id';
|
||||
$table->sortOptions['database_field__id'] = $database->field_sort;
|
||||
\IPS\Member::loggedIn()->language()->words['sort_database_field__id'] = \IPS\Member::loggedIn()->language()->addToStack('database_field__id');
|
||||
break;
|
||||
case 'member_id':
|
||||
$sortBy[ $database->field_sort ] = 'database_field__member';
|
||||
$table->sortOptions['database_field__member'] = $database->field_sort;
|
||||
\IPS\Member::loggedIn()->language()->words['sort_database_field__member'] = \IPS\Member::loggedIn()->language()->addToStack('database_field__member');
|
||||
break;
|
||||
case 'record_rating':
|
||||
$sortBy[ $database->field_sort ] = 'database_field__rating';
|
||||
$table->sortOptions['rating'] = $database->field_sort;
|
||||
\IPS\Member::loggedIn()->language()->words['sort_database_field__rating'] = \IPS\Member::loggedIn()->language()->addToStack('database_field__rating');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !$database->options['comments'] )
|
||||
{
|
||||
unset ( $sortBy['record_last_comment'] );
|
||||
unset ( $sortBy['record_comments'] );
|
||||
unset ( $table->sortOptions['record_last_comment'] );
|
||||
unset ( $table->sortOptions['record_comments'] );
|
||||
unset ( $table->sortOptions['last_comment'] );
|
||||
unset ( $table->sortOptions['num_comments'] );
|
||||
}
|
||||
|
||||
if ( !$database->options['reviews'] and !$category->allow_rating )
|
||||
{
|
||||
unset ( $table->sortOptions['num_reviews'] );
|
||||
unset( $table->sortOptions['rating'] );
|
||||
}
|
||||
|
||||
/* If the sort field isn't one of the above, best add it */
|
||||
if ( mb_substr( $database->field_sort, 0, 6 ) === 'field_' )
|
||||
{
|
||||
if ( $database->field_title !== mb_substr( $database->field_sort, 6 ) )
|
||||
{
|
||||
$sortBy[ $database->field_sort ] = \IPS\Member::loggedIn()->language()->addToStack( 'content_field_' . mb_substr( $database->field_sort, 6 ) );
|
||||
$table->sortOptions[ $database->field_sort ] = $database->field_sort;
|
||||
}
|
||||
}
|
||||
|
||||
$table->advancedSearch = array(
|
||||
'record_type' => array( \IPS\Helpers\Table\SEARCH_SELECT, array( 'options' => $filterOptions ) ),
|
||||
'sort_by' => array( \IPS\Helpers\Table\SEARCH_SELECT, array( 'options' => $sortBy ) ),
|
||||
'sort_direction' => array( \IPS\Helpers\Table\SEARCH_SELECT, array( 'options' => array(
|
||||
'asc' => 'asc',
|
||||
'desc' => 'desc',
|
||||
) )
|
||||
),
|
||||
'time_frame' => array( \IPS\Helpers\Table\SEARCH_SELECT, array( 'options' => $timeFrameOptions ) ),
|
||||
'cms_record_i_started' => array( \IPS\Helpers\Table\SEARCH_CHECKBOX, array() ),
|
||||
);
|
||||
|
||||
foreach( $customFields as $obj )
|
||||
{
|
||||
if ( $obj->filter )
|
||||
{
|
||||
\IPS\Member::loggedIn()->language()->words['content_field_' . $obj->id ] = $obj->_title;
|
||||
if ( \in_array( $obj->type, array( 'Date', 'DateRange' ) ) )
|
||||
{
|
||||
$table->advancedSearch[ 'content_field_' . $obj->id ] = array( \IPS\Helpers\Table\SEARCH_DATE_RANGE, array( 'noDefault' => true ) );
|
||||
}
|
||||
else if ( $obj->type == 'Number' )
|
||||
{
|
||||
$table->advancedSearch[ 'content_field_' . $obj->id ] = array( \IPS\Helpers\Table\SEARCH_NUMERIC_TEXT, array( 'noDefault' => true ) );
|
||||
}
|
||||
else if ( $obj->type == 'YesNo' )
|
||||
{
|
||||
$table->advancedSearch[ 'content_field_' . $obj->id ] = array( \IPS\Helpers\Table\SEARCH_BOOL, array( 'noDefault' => true ) );
|
||||
}
|
||||
else if ( $obj->type == 'Member' )
|
||||
{
|
||||
/* Don't show this on the custom modal form because you cannot have two autocompletes with the same name on the same page, and the fix is more invasive than the value of this feature on the modal.
|
||||
The purpose of this is to show in the sidebar filter form */
|
||||
if ( ! isset( \IPS\Request::i()->advancedSearchForm ) )
|
||||
{
|
||||
$like = array();
|
||||
foreach( $v as $val )
|
||||
{
|
||||
if ( $val === 0 or ! empty( $val ) )
|
||||
{
|
||||
$like[] = "CONCAT( ',', " . mb_substr( $k, 8 ) . ", ',') LIKE '%," . \IPS\Db::i()->real_escape_string( $val ) . ",%'";
|
||||
}
|
||||
}
|
||||
|
||||
$table->where[] = array( '( ' . \IPS\Db::i()->in( mb_substr( $k, 8 ), $v ) . ( count( $like ) ? " OR (" . implode( ' OR ', $like ) . ') )' : ')' ) );
|
||||
$table->advancedSearch[ 'content_field_' . $obj->id ] = array( \IPS\Helpers\Table\SEARCH_MEMBER, array( 'noDefault' => true, 'multiple' => NULL ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( $v !== '___any___' )
|
||||
{
|
||||
if ( is_bool( $v ) )
|
||||
$table->advancedSearch[ 'content_field_' . $obj->id ] = array( \IPS\Helpers\Table\SEARCH_SELECT, array( 'options' => $obj->extra, 'multiple' => TRUE, 'noDefault' => true ) );
|
||||
}
|
||||
|
||||
$table->advancedSearch['sort_by'][1]['options']['field_' . $obj->id ] = 'content_field_' . $obj->id;
|
||||
}
|
||||
|
||||
if ( \in_array( $obj->type, array( 'Date', 'DateRange' ) ) )
|
||||
{
|
||||
$table->sortOptions[ 'field_' . $obj->id ] = 'CAST(`field_' . $obj->id . '` AS UNSIGNED)';
|
||||
}
|
||||
else if ( $obj->type == 'Number' )
|
||||
{
|
||||
$table->sortOptions[ 'field_' . $obj->id ] = 'LENGTH(`field_' . $obj->id . '`) ' . $table->sortDirection . ',`field_' . $obj->id . '`';
|
||||
}
|
||||
else
|
||||
{
|
||||
$table->sortOptions[ 'field_' . $obj->id ] = isset( $table->sortOptions[ 'field_' . $obj->id ] ) ? $table->sortOptions[ 'field_' . $obj->id ] : 'field_' . $obj->id;
|
||||
}
|
||||
}
|
||||
|
||||
$table->advancedSearchCallback = function( $table, $values ) use ( $database, $sortBy, $customFields )
|
||||
{
|
||||
/* Type */
|
||||
foreach( $values as $k => $v )
|
||||
{
|
||||
if ( mb_substr( $k, 0, 14 ) === 'content_field_' )
|
||||
{
|
||||
$key = mb_substr( $k, 14 );
|
||||
$concat = ',';
|
||||
$displayValue = $customFields[ $key ]->displayValue( $v );
|
||||
|
||||
if ( $customFields[ $key ]->type === 'Member' )
|
||||
{
|
||||
if ( \is_array( $v ) and \count( $v ) )
|
||||
{
|
||||
/* YesNo fields are false or true */
|
||||
if ( $v === false )
|
||||
$newValue = array();
|
||||
$newDisplayValue = array();
|
||||
$concat = '\n';
|
||||
|
||||
foreach( $v as $member )
|
||||
{
|
||||
$table->where[] = array( '(' . mb_substr( $k, 8 ) . ' IS NULL or ' . mb_substr( $k, 8 ) . '=0)' );
|
||||
if ( $member instanceof \IPS\Member )
|
||||
{
|
||||
$newDisplayValue[] = $member->name;
|
||||
$newValue[] = $member->member_id;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
$displayValue = implode( ', ', $newDisplayValue );
|
||||
$v = $newValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The content_field_x can be an empty array from the member form */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ( \is_array( $v ) )
|
||||
{
|
||||
if ( array_key_exists( 'start', $v ) or array_key_exists( 'end', $v ) )
|
||||
{
|
||||
$start = ( $v['start'] instanceof \IPS\DateTime ) ? $v['start']->getTimestamp() : \intval( $v['start'] );
|
||||
$end = ( $v['end'] instanceof \IPS\DateTime ) ? $v['end']->getTimestamp() : \intval( $v['end'] );
|
||||
|
||||
if ( $start or $end )
|
||||
{
|
||||
$table->where[] = array( mb_substr( $k, 8 ) . "=1" );
|
||||
$table->where[] = array( '( ' . mb_substr( $k, 8 ) . ' BETWEEN ' . $start . ' AND ' . $end . ' )' );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( $v !== 0 and ! $v )
|
||||
$like = array();
|
||||
foreach( $v as $val )
|
||||
{
|
||||
$table->where[] = array( mb_substr( $k, 8 ) . " IS NULL" );
|
||||
if ( $val === 0 or ! empty( $val ) )
|
||||
{
|
||||
$like[] = "CONCAT( '{$concat}', " . mb_substr( $k, 8 ) . ", '{$concat}') LIKE '%{$concat}" . \IPS\Db::i()->real_escape_string( $val ) . "{$concat}%'";
|
||||
}
|
||||
}
|
||||
|
||||
$table->where[] = array( '( ' . \IPS\Db::i()->in( mb_substr( $k, 8 ), $v ) . ( \count( $like ) ? " OR (" . implode( ' OR ', $like ) . ') )' : ')' ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( $v !== '___any___' )
|
||||
{
|
||||
if ( \is_bool( $v ) )
|
||||
{
|
||||
/* YesNo fields are false or true */
|
||||
if ( $v === false )
|
||||
{
|
||||
$table->where[] = array( '(' . mb_substr( $k, 8 ) . ' IS NULL or ' . mb_substr( $k, 8 ) . '=0)' );
|
||||
}
|
||||
else
|
||||
{
|
||||
$table->where[] = array( mb_substr( $k, 8 ) . "=1" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$table->where[] = array( mb_substr( $k, 8 ) . "=?", $v );
|
||||
if ( $v !== 0 and ! $v )
|
||||
{
|
||||
$table->where[] = array( mb_substr( $k, 8 ) . " IS NULL" );
|
||||
}
|
||||
else
|
||||
{
|
||||
$table->where[] = array( mb_substr( $k, 8 ) . "=?", $v );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\cms\modules\front\database\category::$activeFilters[ $key ] = array( 'field' => $customFields[ $key ], 'value' => $displayValue );
|
||||
}
|
||||
|
||||
$key = mb_substr( $k, 14 );
|
||||
\IPS\cms\modules\front\database\category::$activeFilters[ $key ] = array( 'field' => $customFields[ $key ], 'value' => $customFields[ $key ]->displayValue( $v ) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $values['record_type'] ) )
|
||||
{
|
||||
switch ( $values['record_type'] )
|
||||
{
|
||||
case 'open':
|
||||
$table->where[] = 'record_locked=0';
|
||||
break;
|
||||
case 'locked':
|
||||
$table->where[] = 'record_locked=1';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Sort */
|
||||
if ( isset( $values['sort_by'] ) and isset( $sortBy[ $values['sort_by'] ] ) )
|
||||
{
|
||||
if ( isset( $customFields[ mb_substr( $values['sort_by'], 6 ) ] ) and $customFields[ mb_substr( $values['sort_by'], 6 ) ]->type == 'Number' )
|
||||
{
|
||||
$table->sortOptions[ $values['sort_by'] ] = 'LENGTH(`' . $values['sort_by'] . '`) ' . $table->sortDirection . ',`' . $values['sort_by'] . '`';
|
||||
}
|
||||
elseif( isset( $customFields[ mb_substr( $values['sort_by'], 6 ) ] ) and $customFields[ mb_substr( $values['sort_by'], 6 ) ]->type == 'Date' )
|
||||
{
|
||||
$table->sortOptions[ $values['sort_by'] ] = 'CAST(`' . $values['sort_by'] . '` AS UNSIGNED)';
|
||||
}
|
||||
else
|
||||
{
|
||||
$table->sortOptions[ $values['sort_by'] ] = $values['sort_by'];
|
||||
}
|
||||
|
||||
$table->sortBy = $values['sort_by'];
|
||||
$table->sortDirection = $values['sort_direction'];
|
||||
}
|
||||
|
||||
/* Cutoff */
|
||||
$days = NULL;
|
||||
if ( isset( $values['time_frame'] ) )
|
||||
{
|
||||
switch ( $values['time_frame'] )
|
||||
{
|
||||
case 'today':
|
||||
$days = 1;
|
||||
break;
|
||||
case 'last_5_days':
|
||||
$days = 5;
|
||||
break;
|
||||
case 'last_7_days':
|
||||
$days = 7;
|
||||
break;
|
||||
case 'last_10_days':
|
||||
$days = 10;
|
||||
break;
|
||||
case 'last_15_days':
|
||||
$days = 15;
|
||||
break;
|
||||
case 'last_20_days':
|
||||
$days = 20;
|
||||
break;
|
||||
case 'last_25_days':
|
||||
$days = 25;
|
||||
break;
|
||||
case 'last_30_days':
|
||||
$days = 30;
|
||||
break;
|
||||
case 'last_60_days':
|
||||
$days = 60;
|
||||
break;
|
||||
case 'last_90_days':
|
||||
$days = 90;
|
||||
break;
|
||||
case 'since_last_visit':
|
||||
$table->where[] = array( 'record_last_comment>?', \IPS\Member::loggedIn()->last_visit );
|
||||
break;
|
||||
}
|
||||
if ( $days !== NULL )
|
||||
{
|
||||
$table->where[] = array( 'record_last_comment>?', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . $days . 'D' ) )->getTimestamp() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* RSS */
|
||||
if ( $database->rss )
|
||||
{
|
||||
$rssUrl = $table->baseUrl->setQueryString('rss', 1 );
|
||||
$rssName = $database->_title . ': ' . $category->metaTitle();
|
||||
\IPS\Output::i()->rssFeeds[ $rssName ] = $rssUrl;
|
||||
|
||||
/* Show RSS feed */
|
||||
if ( isset( \IPS\Request::i()->rss ) )
|
||||
{
|
||||
$rssName = \IPS\Member::loggedIn()->language()->get('content_db_' . $database->id ) . ': ' . $category->metaTitle();
|
||||
$document = \IPS\Xml\Rss::newDocument( $table->baseUrl, $rssName, $rssName );
|
||||
$contentField = 'field_' . $database->field_content;
|
||||
|
||||
foreach ( $table->getRows( array() ) as $record )
|
||||
{
|
||||
if ( ! $record->hidden() )
|
||||
{
|
||||
$content = $record->$contentField;
|
||||
|
||||
if ( $record->record_image )
|
||||
{
|
||||
$content = \IPS\cms\Theme::i()->getTemplate( $category->_template_listing, 'cms', 'database' )->rssItemWithImage( $content, $record->record_image );
|
||||
}
|
||||
if ( isset( $values['cms_record_i_started'] ) and $values['cms_record_i_started'] and \IPS\Member::loggedIn()->member_id )
|
||||
{
|
||||
$table->where[] = 'cms_custom_database_' . $database->id . '.member_id=' . \IPS\Member::loggedIn()->member_id;
|
||||
}
|
||||
|
||||
$document->addItem( $record->_title, $record->url(), $content, \IPS\DateTime::ts( ( $record->record_last_comment > $record->record_publish_date ) ? $record->record_publish_date : $record->record_last_comment ), $record->_id );
|
||||
if ( isset( $values['record_type'] ) )
|
||||
{
|
||||
switch ( $values['record_type'] )
|
||||
{
|
||||
case 'open':
|
||||
$table->where[] = 'record_locked=0';
|
||||
break;
|
||||
case 'locked':
|
||||
$table->where[] = 'record_locked=1';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* @note application/rss+xml is not a registered IANA mime-type so we need to stick with text/xml for RSS */
|
||||
\IPS\Output::i()->sendOutput( $document->asXML(), 200, 'text/xml' );
|
||||
|
||||
/* Sort */
|
||||
if ( isset( $values['sort_by'] ) and isset( $sortBy[ $values['sort_by'] ] ) )
|
||||
{
|
||||
if ( isset( $customFields[ mb_substr( $values['sort_by'], 6 ) ] ) and $customFields[ mb_substr( $values['sort_by'], 6 ) ]->type == 'Number' )
|
||||
{
|
||||
$table->sortOptions[ $values['sort_by'] ] = 'LENGTH(`' . $values['sort_by'] . '`) ' . $table->sortDirection . ',`' . $values['sort_by'] . '`';
|
||||
}
|
||||
elseif( isset( $customFields[ mb_substr( $values['sort_by'], 6 ) ] ) and $customFields[ mb_substr( $values['sort_by'], 6 ) ]->type == 'Date' )
|
||||
{
|
||||
$table->sortOptions[ $values['sort_by'] ] = 'CAST(`' . $values['sort_by'] . '` AS UNSIGNED)';
|
||||
}
|
||||
else
|
||||
{
|
||||
$table->sortOptions[ $values['sort_by'] ] = $values['sort_by'];
|
||||
}
|
||||
|
||||
$table->sortBy = $values['sort_by'];
|
||||
$table->sortDirection = $values['sort_direction'];
|
||||
}
|
||||
|
||||
/* Cutoff */
|
||||
$days = NULL;
|
||||
if ( isset( $values['time_frame'] ) )
|
||||
{
|
||||
switch ( $values['time_frame'] )
|
||||
{
|
||||
case 'today':
|
||||
$days = 1;
|
||||
break;
|
||||
case 'last_5_days':
|
||||
$days = 5;
|
||||
break;
|
||||
case 'last_7_days':
|
||||
$days = 7;
|
||||
break;
|
||||
case 'last_10_days':
|
||||
$days = 10;
|
||||
break;
|
||||
case 'last_15_days':
|
||||
$days = 15;
|
||||
break;
|
||||
case 'last_20_days':
|
||||
$days = 20;
|
||||
break;
|
||||
case 'last_25_days':
|
||||
$days = 25;
|
||||
break;
|
||||
case 'last_30_days':
|
||||
$days = 30;
|
||||
break;
|
||||
case 'last_60_days':
|
||||
$days = 60;
|
||||
break;
|
||||
case 'last_90_days':
|
||||
$days = 90;
|
||||
break;
|
||||
case 'since_last_visit':
|
||||
$table->where[] = array( 'record_last_comment>?', \IPS\Member::loggedIn()->last_visit );
|
||||
break;
|
||||
}
|
||||
if ( $days !== NULL )
|
||||
{
|
||||
$table->where[] = array( 'record_last_comment>?', \IPS\DateTime::create()->sub( new \DateInterval( 'P' . $days . 'D' ) )->getTimestamp() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* RSS */
|
||||
if ( $database->rss )
|
||||
{
|
||||
$rssUrl = $table->baseUrl->setQueryString('rss', 1 );
|
||||
$rssName = $database->_title . ': ' . $category->metaTitle();
|
||||
\IPS\Output::i()->rssFeeds[ $rssName ] = $rssUrl;
|
||||
|
||||
/* Show RSS feed */
|
||||
if ( isset( \IPS\Request::i()->rss ) )
|
||||
{
|
||||
$rssName = \IPS\Member::loggedIn()->language()->get('content_db_' . $database->id ) . ': ' . $category->metaTitle();
|
||||
$document = \IPS\Xml\Rss::newDocument( $table->baseUrl, $rssName, $rssName );
|
||||
$contentField = 'field_' . $database->field_content;
|
||||
|
||||
foreach ( $table->getRows( array() ) as $record )
|
||||
{
|
||||
if ( ! $record->hidden() )
|
||||
{
|
||||
$content = $record->$contentField;
|
||||
|
||||
if ( $record->record_image )
|
||||
{
|
||||
$content = \IPS\cms\Theme::i()->getTemplate( $category->_template_listing, 'cms', 'database' )->rssItemWithImage( $content, $record->record_image );
|
||||
}
|
||||
|
||||
$document->addItem( $record->_title, $record->url(), $content, \IPS\DateTime::ts( ( $record->record_last_comment > $record->record_publish_date ) ? $record->record_publish_date : $record->record_last_comment ), $record->_id );
|
||||
}
|
||||
}
|
||||
|
||||
/* @note application/rss+xml is not a registered IANA mime-type so we need to stick with text/xml for RSS */
|
||||
\IPS\Output::i()->sendOutput( $document->asXML(), 200, 'text/xml', array(), TRUE );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->metaTags['title'] = $category->metaTitle();
|
||||
\IPS\Output::i()->metaTags['description'] = $category->metaDescription();
|
||||
\IPS\Output::i()->metaTags['og:title'] = $category->metaTitle();
|
||||
\IPS\Output::i()->metaTags['og:description'] = $category->metaDescription();
|
||||
\IPS\Output::i()->linkTags['canonical'] = (string) $category->url();
|
||||
|
||||
/* Set breadcrumb */
|
||||
if ( \IPS\IPS::classUsesTrait( $category, 'IPS\Content\ClubContainer' ) and $club = $category->club() )
|
||||
{
|
||||
$club->setBreadcrumbs( $category );
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ( $category->parents() as $parent )
|
||||
{
|
||||
\IPS\Output::i()->breadcrumb[] = array( $category->url(), $category->_title );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->breadcrumb[] = array( NULL, $category->_title );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -530,17 +694,24 @@ class _category extends \IPS\cms\Databases\Controller
|
||||
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'records/list.css', 'cms', 'front' ) );
|
||||
|
||||
$stringTable = (string) $table;
|
||||
$stringTable = ( ( $category->hasChildren() AND $category->show_records ) OR ! $category->hasChildren() ) ? (string) $table : '';
|
||||
|
||||
\IPS\cms\Databases\Dispatcher::i()->output .= \IPS\cms\Theme::i()->getTemplate( $category->_template_listing, 'cms', 'database' )->categoryHeader( $category, $stringTable, static::$activeFilters );
|
||||
|
||||
if ( ( $category->hasChildren() AND $category->show_records ) OR ! $category->hasChildren() )
|
||||
{
|
||||
\IPS\cms\Databases\Dispatcher::i()->output .= $stringTable;
|
||||
}
|
||||
|
||||
\IPS\Output::i()->title = ( $table->page > 1 ) ? \IPS\Member::loggedIn()->language()->addToStack( 'title_with_page_number', FALSE, array( 'sprintf' => array( $category->pageTitle(), $table->page ) ) ) : $category->pageTitle();
|
||||
\IPS\cms\Databases\Dispatcher::i()->output .= $stringTable;
|
||||
|
||||
\IPS\cms\Databases\Dispatcher::i()->output .= \IPS\cms\Theme::i()->getTemplate( $category->_template_listing, 'cms', 'database' )->categoryFooter( $category, $stringTable, static::$activeFilters );
|
||||
|
||||
$titleSuffix = $database->use_categories ? $category->_title . ' - ' . $category->pageTitle() : $category->pageTitle();
|
||||
|
||||
if( ( $category->hasChildren() AND $category->show_records ) OR ! $category->hasChildren() )
|
||||
{
|
||||
\IPS\Output::i()->title = ( $table->page > 1 ) ? \IPS\Member::loggedIn()->language()->addToStack( 'title_with_page_number', FALSE, array( 'sprintf' => array( $titleSuffix, $table->page ) ) ) : $titleSuffix;
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->title = $titleSuffix;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -564,9 +735,10 @@ class _category extends \IPS\cms\Databases\Controller
|
||||
|
||||
$hasModOptions = FALSE;
|
||||
|
||||
$canHide = ( \IPS\Member::loggedIn()->group['g_hide_own_posts'] == '1' or \in_array( 'IPS\cms\Records' . \IPS\cms\Databases\Dispatcher::i()->databaseId, explode( ',', \IPS\Member::loggedIn()->group['g_hide_own_posts'] ) ) );
|
||||
if ( $recordClass::modPermission( 'lock', NULL, $category ) or
|
||||
$recordClass::modPermission( 'pin', NULL, $category ) or
|
||||
$recordClass::modPermission( 'hide', NULL, $category ) or
|
||||
$canHide or
|
||||
$recordClass::modPermission( 'feature', NULL, $category ) or
|
||||
$fieldsClass::fixedFieldFormShow( 'record_allow_comments' ) or
|
||||
$fieldsClass::fixedFieldFormShow( 'record_expiry_date' ) or
|
||||
@@ -579,7 +751,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 = \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\cms\Databases\Dispatcher::i()->output = \IPS\Output::i()->output = $form->customTemplate( array( \IPS\cms\Theme::i()->getTemplate( $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' ) );
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
namespace IPS\cms\modules\front\database;
|
||||
|
||||
/* 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;
|
||||
@@ -87,11 +87,11 @@ class _index extends \IPS\cms\Databases\Controller
|
||||
}
|
||||
|
||||
/* @note application/rss+xml is not a registered IANA mime-type so we need to stick with text/xml for RSS */
|
||||
\IPS\Output::i()->sendOutput( $document->asXML(), 200, 'text/xml' );
|
||||
\IPS\Output::i()->sendOutput( $document->asXML(), 200, 'text/xml', array(), TRUE );
|
||||
}
|
||||
}
|
||||
|
||||
$page = isset( \IPS\Request::i()->page ) ? intval( \IPS\Request::i()->page ) : 1;
|
||||
$page = isset( \IPS\Request::i()->page ) ? \intval( \IPS\Request::i()->page ) : 1;
|
||||
|
||||
if( $page < 1 )
|
||||
{
|
||||
@@ -111,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 is_array( $database->featured_settings['categories'] ) and count( $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'] ) ) );
|
||||
@@ -133,7 +133,7 @@ class _index extends \IPS\cms\Databases\Controller
|
||||
/* Make sure we are viewing a real page */
|
||||
if ( $page > $pagination['pages'] )
|
||||
{
|
||||
\IPS\Output::i()->redirect( \IPS\Request::i()->url()->setQueryString( 'page', 1 ), NULL, 303 );
|
||||
\IPS\Output::i()->redirect( \IPS\Request::i()->url()->setPage( 'page', 1 ), NULL, 303 );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'database_index/featured.css', 'cms', 'front' ) );
|
||||
@@ -186,7 +186,7 @@ class _index extends \IPS\cms\Databases\Controller
|
||||
$form->class = 'ipsForm_vertical ipsForm_noLabels';
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'category', NULL, TRUE, array(
|
||||
'url' => \IPS\cms\Pages\Page::$currentPage->url()->setQueryString( array( 'do' => 'form', 'page_id' => \IPS\cms\Pages\Page::$currentPage->id ) ),
|
||||
'class' => 'IPS\cms\Categories' . \IPS\cms\Databases\Dispatcher::i()->databaseId,
|
||||
'class' => 'IPS\cms\Categories' . \IPS\cms\Pages\Page::$currentPage->getDatabase()->_id,
|
||||
'permissionCheck' => function( $node )
|
||||
{
|
||||
if ( $node->can( 'view' ) )
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
namespace IPS\cms\modules\front\database;
|
||||
|
||||
/* 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;
|
||||
@@ -73,21 +73,21 @@ class _record extends \IPS\Content\Controller
|
||||
$_tabs = array_keys( $tabs );
|
||||
$tab = isset( \IPS\Request::i()->tab ) ? \IPS\Request::i()->tab : array_shift( $_tabs );
|
||||
$activeTabContents = $record->commentReviews( $tab );
|
||||
$comments = count( $tabs ) ? \IPS\cms\Theme::i()->getTemplate( $record->container()->_template_display, 'cms', 'database' )->commentsAndReviewsTabs( \IPS\Theme::i()->getTemplate( 'global', 'core' )->tabs( $tabs, $tab, $activeTabContents, $record->url(), 'tab', FALSE, TRUE ), md5( $record->url() ) ) : NULL;
|
||||
$comments = \count( $tabs ) ? \IPS\cms\Theme::i()->getTemplate( $record->container()->_template_display, 'cms', 'database' )->commentsAndReviewsTabs( \IPS\Theme::i()->getTemplate( 'global', 'core' )->tabs( $tabs, $tab, $activeTabContents, $record->url(), 'tab', FALSE, TRUE ), md5( $record->url() ) ) : NULL;
|
||||
|
||||
if ( \IPS\Request::i()->isAjax() and ( isset( \IPS\Request::i()->page ) OR isset( \IPS\Request::i()->tab ) ) )
|
||||
if ( \IPS\Request::i()->isAjax() and !isset( \IPS\Request::i()->rating_submitted ) and ( isset( \IPS\Request::i()->page ) OR isset( \IPS\Request::i()->tab ) ) and $activeTabContents )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( $activeTabContents, 200, 'text/html', \IPS\Output::i()->httpHeaders );
|
||||
\IPS\Output::i()->sendOutput( $activeTabContents, 200, 'text/html' );
|
||||
}
|
||||
|
||||
$class = '\IPS\cms\Categories' . $record::$customDatabaseId;
|
||||
$category = $class::load( $record->category_id );
|
||||
$FieldsClass = '\\IPS\\cms\\Fields' . $record::$customDatabaseId;
|
||||
$updateFields = $FieldsClass::fields( $record->fieldValues(), 'edit', $record->container(), $FieldsClass::FIELD_SKIP_TITLE_CONTENT | $FieldsClass::FIELD_DISPLAY_COMMENTFORM );
|
||||
$updateFields = $FieldsClass::fields( $record->fieldValues(), 'edit', $record->container(), $FieldsClass::FIELD_DISPLAY_COMMENTFORM, $record );
|
||||
$form = null;
|
||||
|
||||
/* We need edit permission to change the record */
|
||||
if ( count( $updateFields ) and $record->canEdit() )
|
||||
if ( \count( $updateFields ) and $record->canEdit() )
|
||||
{
|
||||
$form = new \IPS\Helpers\Form( 'update_record', 'update', $record->url()->setQueryString( array( 'd' => $record::$customDatabaseId ) ) );
|
||||
$form->class = 'ipsForm_vertical';
|
||||
@@ -113,18 +113,29 @@ class _record extends \IPS\Content\Controller
|
||||
}
|
||||
}
|
||||
|
||||
if ( count( $customValues ) )
|
||||
if ( \count( $customValues ) )
|
||||
{
|
||||
if ( $values['record_display_field_change'] )
|
||||
{
|
||||
$record->addCommentWhenFiltersChanged( $values );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set excludes for custom field updates. We'll send the notifications later, once we know the new content of the fields. */
|
||||
$record->setFieldQuoteAndMentionExcludes();
|
||||
}
|
||||
|
||||
foreach( $fieldsClass::fields( $customValues, 'edit', $record->category_id ? $category : NULL, $FieldsClass::FIELD_SKIP_TITLE_CONTENT | $FieldsClass::FIELD_DISPLAY_COMMENTFORM ) as $key => $field )
|
||||
foreach( $fieldsClass::fields( $customValues, 'edit', $record->category_id ? $category : NULL, $FieldsClass::FIELD_DISPLAY_COMMENTFORM ) as $key => $field )
|
||||
{
|
||||
$key = 'field_' . $key;
|
||||
$record->$key = $field::stringValue( isset( $values[ $field->name ] ) ? $values[ $field->name ] : NULL );
|
||||
}
|
||||
|
||||
/* Send custom field update notifications */
|
||||
if ( !$values['record_display_field_change'] )
|
||||
{
|
||||
$record->sendFieldQuoteAndMentionNotifications();
|
||||
}
|
||||
|
||||
$record->save();
|
||||
$record->processAfterEdit( $values );
|
||||
@@ -146,7 +157,14 @@ class _record extends \IPS\Content\Controller
|
||||
}
|
||||
|
||||
/* Set record URL as canonical tag */
|
||||
\IPS\Output::i()->linkTags['canonical'] = $record->url();
|
||||
if ( $record::database()->canonical_flag == 1 and ( isset( \IPS\Request::i()->page ) and \IPS\Request::i()->page > 1 ) )
|
||||
{
|
||||
\IPS\Output::i()->linkTags['canonical'] = $record->url()->setPage( 'page', \IPS\Request::i()->page );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->linkTags['canonical'] = $record->url();
|
||||
}
|
||||
|
||||
/* Update location */
|
||||
if( $record->database()->use_categories )
|
||||
@@ -163,7 +181,7 @@ class _record extends \IPS\Content\Controller
|
||||
/* Next unread */
|
||||
try
|
||||
{
|
||||
$nextUnread = $record->nextUnread();
|
||||
$nextUnread = $record->containerHasUnread();
|
||||
}
|
||||
catch( \Exception $e )
|
||||
{
|
||||
@@ -176,6 +194,8 @@ class _record extends \IPS\Content\Controller
|
||||
}
|
||||
|
||||
/* Add Json-LD */
|
||||
$jsonLdText = $record->truncated( TRUE, NULL );
|
||||
|
||||
\IPS\Output::i()->jsonLd['article'] = array(
|
||||
'@context' => "http://schema.org",
|
||||
'@type' => "Article",
|
||||
@@ -184,8 +204,8 @@ class _record extends \IPS\Content\Controller
|
||||
'mainEntityOfPage' => (string) $record->url(),
|
||||
'name' => $record->_title,
|
||||
'headline' => $record->_title,
|
||||
'text' => strip_tags( $record->truncated() ),
|
||||
'articleBody' => strip_tags( $record->truncated() ),
|
||||
'text' => $jsonLdText,
|
||||
'articleBody' => $jsonLdText,
|
||||
'dateCreated' => \IPS\DateTime::ts( $record->record_saved )->format( \IPS\DateTime::ISO8601 ),
|
||||
'datePublished' => \IPS\DateTime::ts( $record->record_publish_date ?: $record->record_saved )->format( \IPS\DateTime::ISO8601 ),
|
||||
'dateModified' => \IPS\DateTime::ts( $record->record_edit_time ?: ( $record->record_publish_date ?: $record->record_saved ) )->format( \IPS\DateTime::ISO8601 ),
|
||||
@@ -193,16 +213,15 @@ class _record extends \IPS\Content\Controller
|
||||
'pageEnd' => $record->commentPageCount(),
|
||||
'author' => array(
|
||||
'@type' => 'Person',
|
||||
'name' => \IPS\Member::load( $record->member_id )->name,
|
||||
'image' => \IPS\Member::load( $record->member_id )->get_photo()
|
||||
'name' => (string) \IPS\Member::load( $record->member_id )->name,
|
||||
'image' => (string) \IPS\Member::load( $record->member_id )->get_photo()
|
||||
),
|
||||
'publisher' => array(
|
||||
'@type' => 'Organization',
|
||||
'name' => \IPS\Member::load( $record->member_id )->name,
|
||||
'image' => \IPS\Member::load( $record->member_id )->get_photo(),
|
||||
'logo' => array(
|
||||
'@type' => 'ImageObject',
|
||||
'url' => \IPS\Member::load( $record->member_id )->get_photo(),
|
||||
'@id' => \IPS\Settings::i()->base_url . '#organization',
|
||||
'member' => array(
|
||||
'@type' => "Person",
|
||||
'name' => \IPS\Member::load( $record->member_id )->name,
|
||||
'image' => (string) \IPS\Member::load( $record->member_id )->get_photo(),
|
||||
)
|
||||
),
|
||||
'interactionStatistic' => array(
|
||||
@@ -223,22 +242,35 @@ class _record extends \IPS\Content\Controller
|
||||
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();
|
||||
\IPS\Output::i()->jsonLd['article']['publisher']['member']['url'] = (string) \IPS\Member::load( $record->member_id )->url();
|
||||
}
|
||||
|
||||
$logo = NULL;
|
||||
if( \IPS\Theme::i()->logo['front'] )
|
||||
{
|
||||
try
|
||||
{
|
||||
$logo = \IPS\File::get( 'core_Theme', \IPS\Theme::i()->logo['front']['url'] )->url;
|
||||
}
|
||||
/* File doesn't exist */
|
||||
catch ( \RuntimeException $e ){}
|
||||
catch ( \DomainException $e ){}
|
||||
}
|
||||
\IPS\Output::i()->jsonLd['article']['publisher']['logo'] = array(
|
||||
'@type' => 'ImageObject',
|
||||
'url' => $logo ? (string) $logo : (string) \IPS\Member::load( $record->member_id )->get_photo(),
|
||||
);
|
||||
|
||||
/* 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]
|
||||
'url' => (string) $imageObj->url
|
||||
);
|
||||
}
|
||||
/* File doesn't exist */
|
||||
@@ -257,26 +289,7 @@ class _record extends \IPS\Content\Controller
|
||||
);
|
||||
}
|
||||
|
||||
if( $record->averageReviewRating() )
|
||||
{
|
||||
\IPS\Output::i()->jsonLd['article']['aggregateRating'] = array(
|
||||
'@type' => 'AggregateRating',
|
||||
'ratingValue' => $record->averageReviewRating(),
|
||||
'reviewCount' => $record->record_reviews,
|
||||
'bestRating' => \IPS\Settings::i()->reviews_rating_out_of
|
||||
);
|
||||
}
|
||||
elseif( $record->container()->allow_rating AND $record->averageRating() AND $record->numberOfRatings() )
|
||||
{
|
||||
\IPS\Output::i()->jsonLd['article']['aggregateRating'] = array(
|
||||
'@type' => 'AggregateRating',
|
||||
'ratingValue' => $record->averageRating(),
|
||||
'ratingCount' => $record->numberOfRatings(),
|
||||
'bestRating' => \IPS\Settings::i()->reviews_rating_out_of
|
||||
);
|
||||
}
|
||||
|
||||
if( $record::database()->options['reviews'] )
|
||||
if( $record::database()->options['reviews'] or $record->container()->allow_rating )
|
||||
{
|
||||
\IPS\Output::i()->jsonLd['article']['interactionStatistic'][] = array(
|
||||
'@type' => 'InteractionCounter',
|
||||
@@ -296,12 +309,12 @@ 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( get_class( $record ), 4 ) ) ), 'item' => $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 );
|
||||
\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 ) { }
|
||||
|
||||
@@ -412,14 +425,16 @@ class _record extends \IPS\Content\Controller
|
||||
);
|
||||
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'system/diff.css', 'core', 'admin' ) );
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'codemirror/diff_match_patch.js', 'core', 'interface' ) );
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'codemirror/diff_match_patch.js', 'core', 'interface' ) );
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js('front_records.js', 'cms' ) );
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'codemirror/codemirror.js', 'core', 'interface' ) );
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'codemirror/codemirror.css', 'core', 'interface' ) );
|
||||
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'records/record.css', 'cms', 'front' ) );
|
||||
|
||||
/* Output */
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->blankTemplate( $table ), 200, 'text/html', \IPS\Output::i()->httpHeaders );
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->blankTemplate( $table ), 200, 'text/html' );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -529,12 +544,27 @@ class _record extends \IPS\Content\Controller
|
||||
$conflicts = array();
|
||||
$form = new \IPS\Helpers\Form( 'form', 'content_revision_restore' );
|
||||
|
||||
/* Add a "cancel" button that will take you back to the previous page */
|
||||
array_unshift( $form->actionButtons, \IPS\Theme::i()->getTemplate( 'forms', 'core', 'global' )->button( 'cancel', 'link', $record->url()->setQueryString( array( 'do' => 'revisions', 'd' => $record::$customDatabaseId ) ), 'ipsButton ipsButton_link', array( 'tabindex' => '3', 'accesskey' => 'c' ) ) );
|
||||
|
||||
/* Build up our data set */
|
||||
$conflicts = $revision->getDiffHtmlTables( $record::$customDatabaseId, $record, true );
|
||||
|
||||
foreach( $conflicts as $conflict )
|
||||
/* If there is only one change, then clicking restore naturally means to revert that single change, so we don't need a form */
|
||||
if( \count( $conflicts ) === 1 )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'conflict_' . $conflict['field']->id, 'no', false, array( 'options' => array( 'old' => '', 'new' => '' ) ) ) );
|
||||
foreach( $conflicts as $conflict )
|
||||
{
|
||||
$form->hiddenValues[ 'conflict_' . $conflict['field']->id ] = 'old';
|
||||
}
|
||||
}
|
||||
/* Otherwise if multiple fields have changes to compare, let the admin decide what to do */
|
||||
else
|
||||
{
|
||||
foreach( $conflicts as $conflict )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'conflict_' . $conflict['field']->id, 'no', false, array( 'options' => array( 'old' => '', 'new' => '' ) ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $values = $form->values() )
|
||||
@@ -553,7 +583,7 @@ class _record extends \IPS\Content\Controller
|
||||
$record->save();
|
||||
$revision->delete();
|
||||
|
||||
\IPS\Output::i()->redirect( $record->url('revisions') );
|
||||
\IPS\Output::i()->redirect( $record->url(), 'content_revision_restored' );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -573,7 +603,8 @@ class _record extends \IPS\Content\Controller
|
||||
\IPS\Output::i()->title = $title;
|
||||
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'system/diff.css', 'core', 'admin' ) );
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'codemirror/diff_match_patch.js', 'core', 'interface' ) );
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'codemirror/diff_match_patch.js', 'core', 'interface' ) );
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js('front_records.js', 'cms' ) );
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'codemirror/codemirror.js', 'core', 'interface' ) );
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'codemirror/codemirror.css', 'core', 'interface' ) );
|
||||
|
||||
@@ -633,8 +664,8 @@ class _record extends \IPS\Content\Controller
|
||||
$hasModOptions = FALSE;
|
||||
|
||||
if ( $recordClass::modPermission( 'lock', NULL, $category ) or
|
||||
$recordClass::modPermission( 'pin', NULL, $category ) or
|
||||
$recordClass::modPermission( 'hide', NULL, $category ) or
|
||||
$recordClass::modPermission( 'pin', NULL, $category ) or
|
||||
$record->canHide() or
|
||||
$recordClass::modPermission( 'feature', NULL, $category ) or
|
||||
$fieldsClass::fixedFieldFormShow( 'record_allow_comments' ) or
|
||||
$fieldsClass::fixedFieldFormShow( 'record_expiry_date' ) or
|
||||
@@ -669,7 +700,7 @@ class _record extends \IPS\Content\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 = $form->customTemplate( array( \IPS\cms\Theme::i()->getTemplate( $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' ) );
|
||||
|
||||
@@ -690,7 +721,7 @@ class _record extends \IPS\Content\Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark Topic Read
|
||||
* Mark Database Record Read
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
@@ -889,16 +920,4 @@ class _record extends \IPS\Content\Controller
|
||||
\IPS\Output::i()->error( 'node_error', '2T252/F', 403, '' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Moderate
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function moderate()
|
||||
{
|
||||
parent::moderate();
|
||||
|
||||
\IPS\cms\Databases\Dispatcher::i()->output = \IPS\Output::i()->output;
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@
|
||||
namespace IPS\cms\modules\front\database;
|
||||
|
||||
/* 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;
|
||||
@@ -74,6 +74,7 @@ class _topic extends \IPS\Dispatcher\Controller
|
||||
/**
|
||||
* Database
|
||||
*
|
||||
* @param mixed $data Data
|
||||
* @return void
|
||||
*/
|
||||
public function _database( $data )
|
||||
@@ -98,12 +99,13 @@ class _topic extends \IPS\Dispatcher\Controller
|
||||
);
|
||||
}
|
||||
|
||||
return $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ) );
|
||||
return $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Category
|
||||
*
|
||||
* @param mixed $data Data
|
||||
* @return void
|
||||
*/
|
||||
public function _category( $data )
|
||||
@@ -129,7 +131,7 @@ class _topic extends \IPS\Dispatcher\Controller
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=cms&module=database&controller=topic&do=form&id={$values['topic_id']}", 'front', 'topic_copy', $this->topic->title_seo )->csrf()->setQueryString( array( 'database_id' => $values['database_id'], 'category_id' => $values['select_category']->_id ) ) );
|
||||
}
|
||||
|
||||
return $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ) );
|
||||
return $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -182,7 +184,7 @@ class _topic extends \IPS\Dispatcher\Controller
|
||||
foreach( $recordClass::formElements( $fakeRecord, $category ) AS $key => $element )
|
||||
{
|
||||
/* Skip these */
|
||||
if ( in_array( $key, array( 'record_edit_reason', 'record_edit_show' ) ) )
|
||||
if ( \in_array( $key, array( 'record_edit_reason', 'record_edit_show' ) ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -321,7 +323,7 @@ class _topic extends \IPS\Dispatcher\Controller
|
||||
\IPS\Output::i()->breadcrumb[] = array( $this->topic->url(), $this->topic->mapped( 'title' ) );
|
||||
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack( 'copy_topic_to_database' ) );
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'copy_topic_to_database' );
|
||||
\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::load( $database->page_id ), \IPS\Member::loggedIn()->language()->addToStack( 'copy_topic_to_database' ), $hasModOptions );
|
||||
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\cms\Theme::i()->getTemplate( $database->template_form, 'cms', 'database' ), 'recordForm' ), NULL, $category, $database, \IPS\cms\Pages\Page::load( $database->page_id ), \IPS\Member::loggedIn()->language()->addToStack( 'copy_topic_to_database' ), $hasModOptions );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
namespace IPS\cms\modules\front\pages;
|
||||
|
||||
/* 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;
|
||||
@@ -75,14 +75,21 @@ class _builder extends \IPS\core\modules\front\system\widgets
|
||||
if( mb_strpos( $field, "widget_feed_container_" ) !== FALSE )
|
||||
{
|
||||
/* On means that the all checkbox is ticked */
|
||||
$params[ 'widget_feed_container'] = \IPS\Request::i()->$field == 'on' ? 0 : \IPS\Request::i()->$field;
|
||||
$params[ 'widget_feed_container'] = \IPS\Request::i()->$field == 'on' ? 0 : ( \is_array( \IPS\Request::i()->$field ) ? \IPS\Request::i()->$field : explode( ',', \IPS\Request::i()->$field ) );
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We need to handle tags special */
|
||||
if( $field == 'widget_feed_tags' )
|
||||
{
|
||||
$params[ $field ] = explode( ',', \IPS\Request::i()->$field );
|
||||
$params[ $field ] = \IPS\Request::i()->$field ? explode( ',', \IPS\Request::i()->$field ) : array();
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We need to handle authors special */
|
||||
if( $field == 'widget_feed_author' )
|
||||
{
|
||||
$params[ $field ] = \IPS\Request::i()->$field ? array( \IPS\Member::load( \IPS\Request::i()->$field, 'name' )->member_id ) : array();
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -112,7 +119,7 @@ class _builder extends \IPS\core\modules\front\system\widgets
|
||||
$output = $block->widget()->render();
|
||||
}
|
||||
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->blankTemplate( $output ), 200, 'text/html', \IPS\Output::i()->httpHeaders );
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->blankTemplate( $output ), 200, 'text/html' );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -188,7 +195,7 @@ class _builder extends \IPS\core\modules\front\system\widgets
|
||||
protected function getConfiguration()
|
||||
{
|
||||
/* Standard widget area, allow the core stuff to handle this */
|
||||
if( in_array( \IPS\Request::i()->area, array( 'sidebar', 'header', 'footer' ) ) )
|
||||
if( \in_array( \IPS\Request::i()->area, array( 'sidebar', 'header', 'footer' ) ) )
|
||||
{
|
||||
return parent::getConfiguration();
|
||||
}
|
||||
@@ -241,11 +248,20 @@ class _builder extends \IPS\core\modules\front\system\widgets
|
||||
$values = $widget->preConfig( $values );
|
||||
}
|
||||
|
||||
/* Special advanced builder stuff */
|
||||
if ( \in_array( 'IPS\Widget\Builder', class_implements( $widget ) ) )
|
||||
{
|
||||
if( isset( $values['widget_adv__background_custom_image'] ) and $values['widget_adv__background_custom_image'] )
|
||||
{
|
||||
$values['widget_adv__background_custom_image'] = (string) $values['widget_adv__background_custom_image'];
|
||||
}
|
||||
}
|
||||
|
||||
$blocks[ $k ]['configuration'] = $values;
|
||||
\IPS\Db::i()->insert( 'cms_page_widget_areas', array( 'area_page_id' => \IPS\Request::i()->pageID, 'area_area' => \IPS\Request::i()->pageArea, 'area_widgets' => json_encode( $blocks ) ), TRUE );
|
||||
\IPS\Output::i()->json( 'OK' );
|
||||
}
|
||||
\IPS\Output::i()->output = $widget->configuration()->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'widgets', 'core' ) ), 'formTemplate' ), $widget );
|
||||
\IPS\Output::i()->output = $widget->configuration()->customTemplate( array( \IPS\Theme::i()->getTemplate( 'widgets', 'core' ), 'formTemplate' ), $widget );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -319,13 +335,13 @@ class _builder extends \IPS\core\modules\front\system\widgets
|
||||
}
|
||||
|
||||
/* Anything to update? */
|
||||
if ( count( $widgets ) > count( $newOrder ) )
|
||||
if ( \count( $widgets ) > \count( $newOrder ) )
|
||||
{
|
||||
/* No items left in area, or one has been removed */
|
||||
foreach( $widgets as $widget )
|
||||
{
|
||||
/* If we haven't seen this widget, it's been removed, so add to trash */
|
||||
if ( ! in_array( $widget['unique'], $seen ) )
|
||||
if ( ! \in_array( $widget['unique'], $seen ) )
|
||||
{
|
||||
\IPS\Widget::trash( $widget['unique'], $widget );
|
||||
}
|
||||
@@ -360,7 +376,7 @@ class _builder extends \IPS\core\modules\front\system\widgets
|
||||
*/
|
||||
protected function _checkAndDeleteFromCoreWidgets( $uniqueId, $widgets )
|
||||
{
|
||||
if ( ! in_array( $uniqueId, $widgets ) )
|
||||
if ( ! \in_array( $uniqueId, $widgets ) )
|
||||
{
|
||||
/* This widget hasn't been seen, so it isn't in the cms table */
|
||||
try
|
||||
@@ -378,7 +394,7 @@ class _builder extends \IPS\core\modules\front\system\widgets
|
||||
}
|
||||
|
||||
/* Anything to save? */
|
||||
if ( count( $newWidgets ) )
|
||||
if ( \count( $newWidgets ) )
|
||||
{
|
||||
\IPS\Db::i()->replace( 'core_widget_areas', array( 'app' => 'cms', 'module' => 'pages', 'controller' => 'page', 'widgets' => json_encode( $newWidgets ), 'area' => \IPS\Request::i()->area ) );
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
namespace IPS\cms\modules\front\pages;
|
||||
|
||||
/* 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;
|
||||
@@ -63,6 +63,45 @@ class _page extends \IPS\Dispatcher\Controller
|
||||
|
||||
if ( \IPS\Request::i()->path == $page->full_path )
|
||||
{
|
||||
/* Did we have a trailing slash? */
|
||||
if ( \IPS\Settings::i()->htaccess_mod_rewrite and mb_substr( \IPS\Request::i()->url()->data[ \IPS\Http\Url::COMPONENT_PATH ], -1 ) != '/' )
|
||||
{
|
||||
$url = $page->url();
|
||||
|
||||
foreach( \IPS\Request::i()->url()->queryString as $k => $v )
|
||||
{
|
||||
$url = $url->setQueryString( $k, $v );
|
||||
}
|
||||
|
||||
if ( ! empty( \IPS\Request::i()->url()->fragment ) )
|
||||
{
|
||||
$url = $url->setFragment( \IPS\Request::i()->url()->fragment );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( $url, NULL, 301 );
|
||||
}
|
||||
else if ( ! \IPS\Settings::i()->htaccess_mod_rewrite and ! mb_strstr( \IPS\Request::i()->url()->data[ \IPS\Http\Url::COMPONENT_QUERY ], $page->url()->data[ \IPS\Http\Url::COMPONENT_QUERY ] ) )
|
||||
{
|
||||
$url = $page->url();
|
||||
|
||||
foreach( \IPS\Request::i()->url()->queryString as $k => $v )
|
||||
{
|
||||
if ( mb_substr( $k, 0, 1 ) == '/' and mb_substr( $k, -1 ) != '/' )
|
||||
{
|
||||
$k .= '/';
|
||||
}
|
||||
}
|
||||
|
||||
$url = $url->setQueryString( $k, $v );
|
||||
|
||||
if ( ! empty( \IPS\Request::i()->url()->fragment ) )
|
||||
{
|
||||
$url = $url->setFragment( \IPS\Request::i()->url()->fragment );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( $url, NULL, 301 );
|
||||
}
|
||||
|
||||
/* Just viewing this page, no database categories or records */
|
||||
$permissions = $page->permissions();
|
||||
\IPS\Session::i()->setLocation( $page->url(), explode( ",", $permissions['perm_view'] ), 'loc_cms_viewing_page', array( 'cms_page_' . $page->_id => TRUE ) );
|
||||
@@ -100,9 +139,16 @@ class _page extends \IPS\Dispatcher\Controller
|
||||
}
|
||||
else if ( isset( \IPS\Request::i()->path ) AND \IPS\Request::i()->path != '/' )
|
||||
{
|
||||
/* Sort out pagination for pages */
|
||||
list( $path, $pageNumber ) = \IPS\cms\Pages\Page::getStrippedPagePath( \IPS\Request::i()->path );
|
||||
if( $pageNumber AND !\IPS\Request::i()->page )
|
||||
{
|
||||
\IPS\Request::i()->page = $pageNumber;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$page = \IPS\cms\Pages\Page::loadFromPath( \IPS\Request::i()->path );
|
||||
$page = \IPS\cms\Pages\Page::loadFromPath( $path );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
@@ -191,6 +237,6 @@ class _page extends \IPS\Dispatcher\Controller
|
||||
*/
|
||||
protected function embed()
|
||||
{
|
||||
return $this->__call( 'embed', func_get_args() );
|
||||
return $this->__call( 'embed', \func_get_args() );
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user