Version 4.1.2
This commit is contained in:
1 parent
3ba79295ee
commit
28bd025b35
1131 files changed
+63658
-20579
No files matched your search
@@ -289,12 +289,16 @@ EOF;
|
||||
/**
|
||||
* Delete compiled versions
|
||||
*
|
||||
* @param int|array $ids Integer ID or Array IDs to remove
|
||||
* @param null|int|array $ids Integer ID or Array IDs to remove
|
||||
* @return void
|
||||
*/
|
||||
public static function deleteCompiled( $ids )
|
||||
public static function deleteCompiled( $ids=NULL )
|
||||
{
|
||||
if ( is_numeric( $ids ) )
|
||||
if ( $ids === NULL )
|
||||
{
|
||||
$ids = iterator_to_array( \IPS\Db::i()->select( 'block_id', 'cms_blocks' )->setValueField('block_id') );
|
||||
}
|
||||
else if ( is_numeric( $ids ) )
|
||||
{
|
||||
$ids = array( $ids );
|
||||
}
|
||||
@@ -431,6 +435,14 @@ EOF;
|
||||
unset( $buttons['edit']['data'] );
|
||||
}
|
||||
|
||||
/* View Details */
|
||||
$buttons['details'] = array(
|
||||
'icon' => 'search',
|
||||
'title' => 'block_embed_options',
|
||||
'link' => \IPS\Http\Url::internal( "app=cms&module=pages&controller=blocks&do=embedOptions&id={$this->_id}" ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('block_embed_options') )
|
||||
);
|
||||
|
||||
return $buttons;
|
||||
}
|
||||
|
||||
@@ -447,7 +459,7 @@ EOF;
|
||||
$block_plugin = ( isset( \IPS\Request::i()->block_plugin ) ) ? \IPS\Request::i()->block_plugin : ( $this->id ? $this->plugin : null );
|
||||
|
||||
/* Build form */
|
||||
$form->addtab( 'content_block_form_tab__details' );
|
||||
$form->addTab( 'content_block_form_tab__details' );
|
||||
$form->add( new \IPS\Helpers\Form\Translatable( 'block_name', NULL, TRUE, array(
|
||||
'app' => 'cms',
|
||||
'key' => ( $this->id ? "content_block_name_" . $this->id : NULL )
|
||||
@@ -550,12 +562,12 @@ EOF;
|
||||
|
||||
if ( is_callable( array( $this->widget(), 'configuration' ) ) )
|
||||
{
|
||||
$form->addtab( 'content_block_form_tab__feed' );
|
||||
$form->addTab( 'content_block_form_tab__feed' );
|
||||
$this->widget()->configuration( $form );
|
||||
}
|
||||
}
|
||||
|
||||
$form->addtab( 'content_block_form_tab__content');
|
||||
$form->addTab( 'content_block_form_tab__content');
|
||||
|
||||
if ( $block_type === 'plugin' )
|
||||
{
|
||||
@@ -606,7 +618,8 @@ EOF;
|
||||
$form->add( new \IPS\Helpers\Form\Editor( 'block_content', $this->content, FALSE, array(
|
||||
'app' => 'cms',
|
||||
'key' => 'BlockContent',
|
||||
'autoSaveKey' => 'block-content-' . ( $this->id ? $this->id : 'new' ) ), NULL, NULL, NULL, 'block_content_editor' ) );
|
||||
'autoSaveKey' => 'block-content-' . ( $this->id ? $this->id : 'new' ),
|
||||
'attachIds' => ( $this->id ) ? array( $this->id ) : NULL ), NULL, NULL, NULL, 'block_content_editor' ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -656,15 +669,16 @@ EOF;
|
||||
*/
|
||||
public function formatFormValues( $values )
|
||||
{
|
||||
/* Claim Attachments - we need to adjust the temp key based on presence if this block existed or not */
|
||||
if ( \IPS\Request::i()->block_editor === 'editor' )
|
||||
{
|
||||
\IPS\File::claimAttachments( ( $this->id ) ? 'block-content-' . $this->id : 'block-content-new', $this->id );
|
||||
}
|
||||
|
||||
if ( ! $this->id )
|
||||
{
|
||||
$this->active = 1;
|
||||
$this->save();
|
||||
|
||||
if ( \IPS\Request::i()->block_editor === 'editor' )
|
||||
{
|
||||
\IPS\File::claimAttachments( 'block-content/block-' . $this->id, $this->id );
|
||||
}
|
||||
}
|
||||
|
||||
$config = array();
|
||||
|
||||
@@ -225,6 +225,22 @@ class _Categories extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
|
||||
return static::$database;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to see if this is a valid container ID
|
||||
*
|
||||
* @param int $id Container ID
|
||||
* @reply boolean
|
||||
*/
|
||||
public static function isValidContainerId( $id )
|
||||
{
|
||||
if ( static::$containerIds === NULL )
|
||||
{
|
||||
static::$containerIds = iterator_to_array( \IPS\Db::i()->select( 'category_id', static::$databaseTable, array( array( 'category_database_id=?', static::$customDatabaseId ) ) ) );
|
||||
}
|
||||
|
||||
return in_array( $id, static::$containerIds );
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch All Root Nodes
|
||||
@@ -308,7 +324,7 @@ class _Categories extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
*/
|
||||
public function get_fields()
|
||||
{
|
||||
return $this->_data['fields'] === '*' ? '*' : json_decode( $this->_data['fields'], TRUE );
|
||||
return ( $this->_data['fields'] === '*' OR $this->_data['fields'] === NULL ) ? '*' : json_decode( $this->_data['fields'], TRUE );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -363,7 +379,7 @@ class _Categories extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
public function form( &$form )
|
||||
{
|
||||
/* Build form */
|
||||
$form->addtab( 'content_content_form_tab__config' );
|
||||
$form->addTab( 'content_content_form_tab__config' );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Translatable( 'category_name', NULL, TRUE, array(
|
||||
'app' => 'cms',
|
||||
@@ -477,7 +493,7 @@ class _Categories extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
|
||||
if ( \IPS\Application::appIsEnabled( 'forums' ) )
|
||||
{
|
||||
$form->addtab( 'content_content_form_tab__forum' );
|
||||
$form->addTab( 'content_content_form_tab__forum' );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'category_forum_override', ( $this->id ? $this->forum_override : NULL ), FALSE, array(
|
||||
'togglesOn' => array(
|
||||
@@ -523,11 +539,11 @@ class _Categories extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
|
||||
$form->addTab( 'content_content_form_header__fields' );
|
||||
|
||||
$cats = $this->id ? $this->fields : '*';
|
||||
$options = array();
|
||||
$fieldClass = 'IPS\cms\Fields' . \IPS\Request::i()->database_id;
|
||||
$database = \IPS\cms\Databases::load( \IPS\Request::i()->database_id );
|
||||
|
||||
$cats = $this->id ? ( $this->fields === NULL ? '*' : $this->fields ) : '*';
|
||||
$options = array();
|
||||
$fieldClass = 'IPS\cms\Fields' . \IPS\Request::i()->database_id;
|
||||
$database = \IPS\cms\Databases::load( \IPS\Request::i()->database_id );
|
||||
|
||||
foreach( $fieldClass::data( NULL, NULL, $fieldClass::FIELD_SKIP_TITLE_CONTENT ) as $field )
|
||||
{
|
||||
if ( $field->id !== $database->field_title AND $field->id !== $database->field_content )
|
||||
@@ -793,7 +809,39 @@ class _Categories extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
* @brief FURL changed
|
||||
*/
|
||||
protected $_updatePaths = FALSE;
|
||||
|
||||
|
||||
/**
|
||||
* Disabled permissions
|
||||
* Allow node classes to define permissions that are unselectable in the permission matrix
|
||||
*
|
||||
* @return array array( {group_id} => array( 'read', 'view', 'perm_7' );
|
||||
*/
|
||||
public function disabledPermissions()
|
||||
{
|
||||
$database = \IPS\cms\Databases::load( $this->database_id );
|
||||
$dbPerms = $database->permissions();
|
||||
$disabled = array();
|
||||
|
||||
foreach( array( 'view', 2, 3, 4, 5, 6, 7 ) as $perm )
|
||||
{
|
||||
/* Remove unticked database permissions */
|
||||
if ( $dbPerms['perm_' . $perm ] != '*' )
|
||||
{
|
||||
$db = explode( ',', $dbPerms['perm_' . $perm ] );
|
||||
|
||||
foreach ( \IPS\Member\Group::groups() as $group )
|
||||
{
|
||||
if ( ! in_array( $group->g_id, $db ) )
|
||||
{
|
||||
$disabled[ $group->g_id ][] = $perm;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $disabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get permissions
|
||||
*
|
||||
@@ -936,6 +984,36 @@ class _Categories extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
|
||||
return $this->_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get URL from index data
|
||||
*
|
||||
* @param array $indexData Data from the search index
|
||||
* @param array $itemData Basic data about the item. Only includes columns returned by item::basicDataColumns()
|
||||
* @param array|NULL $containerData Basic data about the author. Only includes columns returned by container::basicDataColumns()
|
||||
* @return \IPS\Http\Url
|
||||
*/
|
||||
public static function urlFromIndexData( $indexData, $itemData, $containerData )
|
||||
{
|
||||
$recordClass = $indexData['index_class'];
|
||||
if ( in_array( 'IPS\Content\Comment', class_parents( $recordClass ) ) )
|
||||
{
|
||||
$recordClass = $recordClass::$itemClass;
|
||||
}
|
||||
if ( $recordClass::$pagePath === NULL )
|
||||
{
|
||||
$recordClass::$pagePath = \IPS\Db::i()->select( array( 'page_full_path' ), 'cms_pages', array( 'page_id=?', $recordClass::database()->page_id ) )->first();
|
||||
}
|
||||
|
||||
if ( $recordClass::database()->use_categories )
|
||||
{
|
||||
return \IPS\Http\Url::internal( "app=cms&module=pages&controller=page&path=" . $recordClass::$pagePath . '/' . $itemData['extra'], 'front', 'content_page_path', $itemData['extra'] );
|
||||
}
|
||||
else
|
||||
{
|
||||
return \IPS\Http\Url::internal( "app=cms&module=pages&controller=page&path=" . $recordClass::$pagePath, 'front', 'content_page_path', '' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get title of category
|
||||
@@ -1233,7 +1311,7 @@ class _Categories extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
{
|
||||
$this->last_record_date = $comment->mapped('date');
|
||||
$this->last_record_member = intval( $comment->author()->member_id );
|
||||
$this->last_record_name = $comment->author()->member_id ? $comment->author()->name : $comment->mapped('author_name');
|
||||
$this->last_record_name = $comment->author()->member_id ? $comment->author()->name : NULL;
|
||||
$this->last_record_seo_name = \IPS\Http\Url::seoTitle( $this->last_poster_name );
|
||||
$this->last_title = $comment->item()->mapped('title');
|
||||
$this->last_seo_title = \IPS\Http\Url::seoTitle( $this->last_title );
|
||||
@@ -1243,8 +1321,8 @@ class _Categories extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
{
|
||||
$this->last_record_date = static::$latestRecordAdded->record_saved;
|
||||
$this->last_record_member = static::$latestRecordAdded->member_id;
|
||||
$this->last_record_name = static::$latestRecordAdded->record_last_comment_name;
|
||||
$this->last_record_seo_name = static::$latestRecordAdded->record_last_comment_seo;
|
||||
$this->last_record_name = static::$latestRecordAdded->member_id ? static::$latestRecordAdded->record_last_comment_name : NULL;
|
||||
$this->last_record_seo_name = static::$latestRecordAdded->member_id ? static::$latestRecordAdded->record_last_comment_seo : NULL;
|
||||
$this->last_title = static::$latestRecordAdded->_title;
|
||||
$this->last_seo_title = \IPS\Http\Url::seoTitle( static::$latestRecordAdded->_title );
|
||||
$this->last_record_id = static::$latestRecordAdded->_id;
|
||||
|
||||
@@ -146,7 +146,7 @@ class _Databases extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* Return all databases
|
||||
*
|
||||
@@ -156,21 +156,38 @@ class _Databases extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
{
|
||||
if ( ! static::$gotAll )
|
||||
{
|
||||
if ( \IPS\Db::i()->checkForTable( static::$databaseTable ) )
|
||||
if ( ! isset( \IPS\Data\Store::i()->cms_databases ) )
|
||||
{
|
||||
\IPS\Data\Store::i()->cms_databases = iterator_to_array( \IPS\Db::i()->select( '*', static::$databaseTable )->setKeyField('database_id') );
|
||||
}
|
||||
|
||||
/* Avoid using SHOW TABLES LIKE / checkForTable() */
|
||||
try
|
||||
{
|
||||
foreach( \IPS\Db::i()->select( '*', static::$databaseTable ) as $db )
|
||||
foreach( \IPS\Data\Store::i()->cms_databases as $db )
|
||||
{
|
||||
$id = $db[ static::$databasePrefix . static::$databaseColumnId ];
|
||||
static::$multitons[ $id ] = static::constructFromData( $db );
|
||||
}
|
||||
}
|
||||
catch( \Exception $e ) { }
|
||||
|
||||
static::$gotAll = true;
|
||||
}
|
||||
|
||||
|
||||
return static::$multitons;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can we promote stuff to Pages?
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function canPromote()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct ActiveRecord from database row
|
||||
*
|
||||
@@ -329,9 +346,19 @@ class _Databases extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
|
||||
foreach( \IPS\Lang::languages() as $id => $lang )
|
||||
{
|
||||
/* Try to get the actual database noun if it has been created */
|
||||
try
|
||||
{
|
||||
$title = $lang->get( 'content_db_lang_pu_' . $database->id );
|
||||
}
|
||||
catch( \Exception $e )
|
||||
{
|
||||
$title = $lang->get('content_database_noun_pu');
|
||||
}
|
||||
|
||||
$fieldTitle[ $id ] = $lang->get('content_fields_is_title');
|
||||
$fieldContent[ $id ] = $lang->get('content_fields_is_content');
|
||||
$catTitle[ $id ] = $lang->get('content_database_noun_pu');
|
||||
$catTitle[ $id ] = $title;
|
||||
$catDesc[ $id ] = '';
|
||||
}
|
||||
|
||||
@@ -660,7 +687,7 @@ class _Databases extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
public function preLoadWords()
|
||||
{
|
||||
/* Skip this during installation / uninstallation as the words won't be loaded */
|
||||
if ( !\IPS\Dispatcher::hasInstance() or \IPS\Dispatcher::i()->controllerLocation === 'setup' OR ( \IPS\Dispatcher::i()->controllerLocation === 'admin' AND ( !\IPS\Dispatcher::i()->module OR \IPS\Dispatcher::i()->module->key === 'applications' ) ) )
|
||||
if ( !\IPS\Dispatcher::hasInstance() or \IPS\Dispatcher::i()->controllerLocation === 'setup' OR ( \IPS\Dispatcher::i()->controllerLocation === 'admin' AND \IPS\Dispatcher::i()->module->key === 'applications' ) )
|
||||
{
|
||||
$this->langLoaded = TRUE;
|
||||
return;
|
||||
@@ -671,17 +698,20 @@ class _Databases extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
\IPS\Member::loggedIn()->language()->words['__indefart_content_record_comments_title_' . $this->id ] = \IPS\Member::loggedIn()->language()->addToStack( '__indefart_content_record_comments_title' );
|
||||
\IPS\Member::loggedIn()->language()->words['__indefart_content_record_reviews_title_' . $this->id ] = \IPS\Member::loggedIn()->language()->addToStack( '__indefart_content_record_reviews_title' );
|
||||
|
||||
\IPS\Member::loggedIn()->language()->words['content_record_comments_title_' . $this->id ] = \IPS\Member::loggedIn()->language()->addToStack( 'content_record_comments_title', FALSE, array( 'sprintf' => array( $this->recordWord( 1, TRUE ) ) ) );
|
||||
\IPS\Member::loggedIn()->language()->words['content_record_reviews_title_' . $this->id ] = \IPS\Member::loggedIn()->language()->addToStack( 'content_record_reviews_title', FALSE, array( 'sprintf' => array( $this->recordWord( 1, TRUE ) ) ) );
|
||||
\IPS\Member::loggedIn()->language()->words['content_record_comments_title_' . $this->id ] = \IPS\Member::loggedIn()->language()->addToStack( 'content_record_comment_title', FALSE, array( 'sprintf' => array( $this->recordWord( 1, TRUE ) ) ) );
|
||||
\IPS\Member::loggedIn()->language()->words['content_record_reviews_title_' . $this->id ] = \IPS\Member::loggedIn()->language()->addToStack( 'content_record_review_title', FALSE, array( 'sprintf' => array( $this->recordWord( 1, TRUE ) ) ) );
|
||||
\IPS\Member::loggedIn()->language()->words['content_record_comments_title_' . $this->id . '_pl' ] = \IPS\Member::loggedIn()->language()->addToStack( 'content_record_comments_title', FALSE, array( 'sprintf' => array( $this->recordWord( 1, TRUE ) ) ) );
|
||||
\IPS\Member::loggedIn()->language()->words['content_record_reviews_title_' . $this->id . '_pl' ] = \IPS\Member::loggedIn()->language()->addToStack( 'content_record_reviews_title', FALSE, array( 'sprintf' => array( $this->recordWord( 1, TRUE ) ) ) );
|
||||
|
||||
\IPS\Member::loggedIn()->language()->words['content_db_lang_su_' . $this->id . '_pl' ] = \IPS\Member::loggedIn()->language()->addToStack( 'content_db_lang_pu_' . $this->id );
|
||||
\IPS\Member::loggedIn()->language()->words['content_db_lang_sl_' . $this->id . '_pl_lc' ] = \IPS\Member::loggedIn()->language()->addToStack( 'content_db_lang_pl_' . $this->id );
|
||||
|
||||
$fieldsClass = '\IPS\cms\Fields' . $this->id;
|
||||
$customFields = $fieldsClass::data( 'view', $this );
|
||||
$customFields = $fieldsClass::databaseFieldIds();
|
||||
|
||||
foreach ( $customFields AS $id => $field)
|
||||
foreach ( $customFields AS $id )
|
||||
{
|
||||
\IPS\Member::loggedIn()->language()->words['sort_field_' . $id] = $field->_title;
|
||||
\IPS\Member::loggedIn()->language()->words['sort_field_' . $id] = \IPS\Member::loggedIn()->language()->addToStack( 'content_field_' . $id );
|
||||
}
|
||||
|
||||
if ( \IPS\Dispatcher::i()->controllerLocation === 'admin' )
|
||||
@@ -722,6 +752,21 @@ class _Databases extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
return $number == 1 ? \IPS\Member::loggedIn()->language()->addToStack("content_db_lang_s{$case}_{$this->id}") : \IPS\Member::loggedIn()->language()->addToStack("content_db_lang_p{$case}_{$this->id}");
|
||||
}
|
||||
|
||||
/**
|
||||
* [ActiveRecord] Save Record
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
if ( isset( \IPS\Data\Store::i()->cms_databases ) )
|
||||
{
|
||||
unset( \IPS\Data\Store::i()->cms_databases );
|
||||
}
|
||||
|
||||
parent::save();
|
||||
}
|
||||
|
||||
/**
|
||||
* [ActiveRecord] Delete Record
|
||||
*
|
||||
@@ -742,9 +787,18 @@ class _Databases extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
$field->delete( TRUE );
|
||||
}
|
||||
|
||||
if ( isset( \IPS\Data\Store::i()->cms_databases ) )
|
||||
{
|
||||
unset( \IPS\Data\Store::i()->cms_databases );
|
||||
}
|
||||
|
||||
/* Delete comments */
|
||||
\IPS\Db::i()->delete( 'cms_database_comments', array( 'comment_database_id=?', $this->id ) );
|
||||
|
||||
|
||||
/* Delete from search index */
|
||||
\IPS\Db::i()->delete( 'core_search_index', array( 'index_class=?', "IPS\cms\Records\Comment" . $this->id ) );
|
||||
\IPS\Db::i()->delete( 'core_search_index', array( 'index_class=?', "IPS\cms\Records\Review" . $this->id ) );
|
||||
|
||||
/* Delete records */
|
||||
\IPS\Db::i()->dropTable( 'cms_custom_database_' . $this->id, TRUE );
|
||||
|
||||
|
||||
@@ -283,6 +283,8 @@ class _Dispatcher extends \IPS\Dispatcher
|
||||
}
|
||||
|
||||
\IPS\Dispatcher::i()->dispatcherController = $controller;
|
||||
|
||||
\IPS\Output::i()->defaultSearchOption = array( "cms_records{$this->databaseId}", "cms_records{$this->databaseId}_pl" );
|
||||
|
||||
/* Add database key to body classes for easier database specific themeing */
|
||||
\IPS\Output::i()->bodyClasses[] = 'cCmsDatabase_' . $database->key;
|
||||
|
||||
@@ -167,6 +167,16 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
|
||||
*/
|
||||
const FIELD_DISPLAY_FILTERS = 16;
|
||||
|
||||
/**
|
||||
* @brief Fields that cannot be title fields
|
||||
*/
|
||||
public static $cannotBeTitleFields = array( 'Editor', 'CheckboxSet', 'YesNo', 'Radio' );
|
||||
|
||||
/**
|
||||
* @brief Fields that cannot be title fields
|
||||
*/
|
||||
public static $cannotBeContentFields = array();
|
||||
|
||||
/**
|
||||
* Load Record
|
||||
*
|
||||
@@ -198,7 +208,7 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
|
||||
*/
|
||||
public static function roots( $permissionCheck='view', $member=NULL, $where=array() )
|
||||
{
|
||||
$permissionCheck = ( \IPS\Dispatcher::i()->controllerLocation === 'admin' ) ? NULL : $permissionCheck;
|
||||
$permissionCheck = ( \IPS\Dispatcher::hasInstance() AND \IPS\Dispatcher::i()->controllerLocation === 'admin' ) ? NULL : $permissionCheck;
|
||||
|
||||
if ( ! isset( static::$cache[ static::$customDatabaseId ][ $permissionCheck ] ) )
|
||||
{
|
||||
@@ -209,7 +219,7 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
|
||||
|
||||
foreach( static::$cache[ static::$customDatabaseId ][ $permissionCheck ] as $id => $obj )
|
||||
{
|
||||
if ( ! in_array( $obj->type, static::$additionalFieldTypes ) AND ( ! class_exists( '\IPS\Helpers\Form\\' . ucfirst( $obj->type ) ) AND ! class_exists( '\IPS\cms\Fields\\' . ucfirst( $obj->type ) ) ) )
|
||||
if ( ! array_key_exists( $obj->type, static::$additionalFieldTypes ) AND ( ! class_exists( '\IPS\Helpers\Form\\' . ucfirst( $obj->type ) ) AND ! class_exists( '\IPS\cms\Fields\\' . ucfirst( $obj->type ) ) ) )
|
||||
{
|
||||
unset( static::$cache[ static::$customDatabaseId ][ $permissionCheck ][ $id ] );
|
||||
continue;
|
||||
@@ -229,6 +239,23 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
|
||||
return static::$cache[ static::$customDatabaseId ][ $permissionCheck ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Just return all field IDs in a database without permission checking
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function databaseFieldIds()
|
||||
{
|
||||
$key = 'cms_fieldids_' . static::$customDatabaseId;
|
||||
|
||||
if ( ! isset( \IPS\Data\Store::i()->$key ) )
|
||||
{
|
||||
\IPS\Data\Store::i()->$key = iterator_to_array( \IPS\Db::i()->select( 'field_id', 'cms_database_fields', array( array( 'field_database_id=?', static::$customDatabaseId ) ) )->setKeyField('field_id') );
|
||||
}
|
||||
|
||||
return \IPS\Data\Store::i()->$key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Field Data
|
||||
*
|
||||
@@ -432,26 +459,53 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
|
||||
|
||||
if ( $display === 'listing' )
|
||||
{
|
||||
if ( $display === 'listing' and ! $row->display_listing )
|
||||
if ( ! $row->display_listing )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$value = $row->truncate( $value, TRUE );
|
||||
|
||||
if ( $value or $value === "0" )
|
||||
if ( $value )
|
||||
{
|
||||
$value = $row->formatForDisplay( $value, $formValue, 'listing', $record );
|
||||
}
|
||||
}
|
||||
else if ( $display === 'display' )
|
||||
else if ( $display === 'display' or $display === 'display_top' or $display === 'display_bottom' )
|
||||
{
|
||||
if ( $display === 'display' and ! $row->display_display )
|
||||
if ( ! $row->display_display )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( $value or $value === "0" )
|
||||
$displayData = $row->display_json;
|
||||
|
||||
if ( $display === 'display_bottom' )
|
||||
{
|
||||
if ( isset( $displayData['display']['where'] ) )
|
||||
{
|
||||
if ( $displayData['display']['where'] !== 'bottom' )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if ( $display === 'display_top' )
|
||||
{
|
||||
if ( isset( $displayData['display']['where'] ) )
|
||||
{
|
||||
if ( $displayData['display']['where'] !== 'top' )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $value )
|
||||
{
|
||||
$value = $row->formatForDisplay( $value, $formValue, 'display', $record );
|
||||
}
|
||||
@@ -488,7 +542,34 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
|
||||
{
|
||||
return (string) \IPS\File::get( static::$uploadStorageExtension, $value )->url;
|
||||
}
|
||||
|
||||
|
||||
if ( $this->type === 'Item' )
|
||||
{
|
||||
if ( ! is_array( $formValue ) and mbs_trstr( $formValue, ',' ) )
|
||||
{
|
||||
$value = explode( ',', $formValue );
|
||||
}
|
||||
else
|
||||
{
|
||||
$value = array( $formValue );
|
||||
}
|
||||
|
||||
if ( count( $value ) and isset( $this->extra['database'] ) and $this->extra['database'] )
|
||||
{
|
||||
$results = array();
|
||||
$class = '\IPS\cms\Records' . $this->extra['database'];
|
||||
$field = $class::$databasePrefix . $class::$databaseColumnMap['title'];
|
||||
$where = array( \IPS\Db::i()->in( $class::$databaseColumnId, $value ) );
|
||||
|
||||
foreach ( $class::getItemsWithPermission( array( $where ), $field, NULL ) as $item )
|
||||
{
|
||||
$results[ $item->_id ] = $item;
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
}
|
||||
|
||||
return $formValue;
|
||||
}
|
||||
else if ( $type === 'processed' )
|
||||
@@ -498,7 +579,7 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
|
||||
|
||||
$options = $this->display_json;
|
||||
|
||||
if ( isset( $options[ $type ]['method'] ) )
|
||||
if ( isset( $options[ $type ]['method'] ) AND $options[ $type ]['method'] !== 'simple' )
|
||||
{
|
||||
if ( in_array( $this->type, static::$mediaFields ) )
|
||||
{
|
||||
@@ -1044,7 +1125,18 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
|
||||
public function displayValue( $value=NULL )
|
||||
{
|
||||
$database = \IPS\cms\Databases::load( static::$customDatabaseId );
|
||||
|
||||
|
||||
if ( class_exists( '\IPS\cms\Fields\\' . ucfirst( $this->type ) ) )
|
||||
{
|
||||
/* Is special! */
|
||||
$class = '\IPS\cms\Fields\\' . ucfirst( $this->type );
|
||||
|
||||
if ( method_exists( $class, 'displayValue' ) )
|
||||
{
|
||||
return $class::displayValue( $value, $this );
|
||||
}
|
||||
}
|
||||
|
||||
switch( ucfirst( $this->type ) )
|
||||
{
|
||||
case 'Upload':
|
||||
@@ -1052,7 +1144,7 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
|
||||
break;
|
||||
case 'Text':
|
||||
case 'TextArea':
|
||||
$this->applyFormatter( $value );
|
||||
$value = $this->applyFormatter( $value );
|
||||
|
||||
/* We don't want the parent adding wordbreak to the title */
|
||||
if ( $this->id == $database->field_title OR $this->id == $database->field_content )
|
||||
@@ -1084,14 +1176,14 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
|
||||
$return = array();
|
||||
foreach( $value as $key )
|
||||
{
|
||||
$return[] = isset( $this->extra[ $key ] ) ? htmlentities( $this->extra[ $key ], \IPS\HTMLENTITIES, 'UTF-8', FALSE ) : htmlentities( $key, \IPS\HTMLENTITIES, 'UTF-8', FALSE );
|
||||
$return[] = isset( $this->extra[ $key ] ) ? htmlspecialchars( $this->extra[ $key ], \IPS\HTMLENTITIES, 'UTF-8', FALSE ) : htmlspecialchars( $key, \IPS\HTMLENTITIES, 'UTF-8', FALSE );
|
||||
}
|
||||
|
||||
return implode( ', ', $return );
|
||||
}
|
||||
else
|
||||
{
|
||||
return ( isset( $this->extra[ $value ] ) ? htmlentities( $this->extra[ $value ], \IPS\HTMLENTITIES, 'UTF-8', FALSE ) : htmlentities( $value, \IPS\HTMLENTITIES, 'UTF-8', FALSE ) );
|
||||
return ( isset( $this->extra[ $value ] ) ? htmlspecialchars( $this->extra[ $value ], \IPS\HTMLENTITIES, 'UTF-8', FALSE ) : htmlspecialchars( $value, \IPS\HTMLENTITIES, 'UTF-8', FALSE ) );
|
||||
}
|
||||
break;
|
||||
case 'Member':
|
||||
@@ -1099,6 +1191,13 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return implode( ', ', array_map( function( $id )
|
||||
{
|
||||
return \IPS\Member::load( $id )->link();
|
||||
}, explode( ',', $value ) ) );
|
||||
}
|
||||
break;
|
||||
case 'Url':
|
||||
if ( \IPS\Dispatcher::hasInstance() AND class_exists( '\IPS\Dispatcher', FALSE ) and \IPS\Dispatcher::i()->controllerLocation === 'front' )
|
||||
@@ -1121,6 +1220,33 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
|
||||
return \IPS\Lang::wordbreak( $time->localeDate() );
|
||||
|
||||
break;
|
||||
case 'Item':
|
||||
if ( ! is_array( $value ) and mb_strstr( $value, ',' ) )
|
||||
{
|
||||
$value = explode( ',', $value );
|
||||
}
|
||||
else
|
||||
{
|
||||
$value = array( $value );
|
||||
}
|
||||
|
||||
if ( count( $value ) and isset( $this->extra['database'] ) and $this->extra['database'] )
|
||||
{
|
||||
$results = array();
|
||||
$class = '\IPS\cms\Records' . $this->extra['database'];
|
||||
$field = $class::$databasePrefix . $class::$databaseColumnMap['title'];
|
||||
$where = array( \IPS\Db::i()->in( $class::$databaseColumnId, $value ) );
|
||||
|
||||
foreach( $class::getItemsWithPermission( array( $where ), $field, NULL ) as $item )
|
||||
{
|
||||
$results[] = $item;
|
||||
}
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'cms', 'front' )->basicRelationship( $results );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Formatters */
|
||||
@@ -1142,40 +1268,46 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
|
||||
*/
|
||||
public function applyFormatter( $value )
|
||||
{
|
||||
switch( $this->format_opts )
|
||||
if ( is_array( $this->format_opts ) and count( $this->format_opts ) )
|
||||
{
|
||||
case 'strtolower':
|
||||
$value = mb_convert_case( $value, MB_CASE_LOWER );
|
||||
break;
|
||||
|
||||
case 'strtoupper':
|
||||
$value = mb_convert_case( $value, MB_CASE_UPPER );
|
||||
break;
|
||||
|
||||
case 'ucfirst':
|
||||
$value = ( mb_strtoupper( mb_substr( $value, 0, 1 ) ) . mb_substr( $value, 1, mb_strlen( $value ) ) );
|
||||
break;
|
||||
|
||||
case 'ucwords':
|
||||
$value = mb_convert_case( $value, MB_CASE_TITLE );
|
||||
break;
|
||||
|
||||
case 'punct':
|
||||
$value = preg_replace( "/\?{1,}/" , "?" , $value );
|
||||
$value = preg_replace( "/(!){1,}/" , "!" , $value );
|
||||
break;
|
||||
|
||||
case 'numerical':
|
||||
$value = \IPS\Member::loggedIn()->language()->formatNumber( $value );
|
||||
break;
|
||||
|
||||
case 'bold':
|
||||
$value = '<strong>' . $value . '</strong>';
|
||||
break;
|
||||
|
||||
case 'italic':
|
||||
$value = '<em>' . $value . '</em>';
|
||||
break;
|
||||
foreach( $this->format_opts as $id => $type )
|
||||
{
|
||||
switch( $type )
|
||||
{
|
||||
case 'strtolower':
|
||||
$value = mb_convert_case( $value, MB_CASE_LOWER );
|
||||
break;
|
||||
|
||||
case 'strtoupper':
|
||||
$value = mb_convert_case( $value, MB_CASE_UPPER );
|
||||
break;
|
||||
|
||||
case 'ucfirst':
|
||||
$value = ( mb_strtoupper( mb_substr( $value, 0, 1 ) ) . mb_substr( $value, 1, mb_strlen( $value ) ) );
|
||||
break;
|
||||
|
||||
case 'ucwords':
|
||||
$value = mb_convert_case( $value, MB_CASE_TITLE );
|
||||
break;
|
||||
|
||||
case 'punct':
|
||||
$value = preg_replace( "/\?{1,}/" , "?" , $value );
|
||||
$value = preg_replace( "/(!){1,}/" , "!" , $value );
|
||||
break;
|
||||
|
||||
case 'numerical':
|
||||
$value = \IPS\Member::loggedIn()->language()->formatNumber( $value );
|
||||
break;
|
||||
|
||||
case 'bold':
|
||||
$value = '<strong>' . $value . '</strong>';
|
||||
break;
|
||||
|
||||
case 'italic':
|
||||
$value = '<em>' . $value . '</em>';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
@@ -1242,9 +1374,7 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
|
||||
*/
|
||||
public function canBeTitleField()
|
||||
{
|
||||
$no = array( 'Address' );
|
||||
|
||||
if ( $this->is_multiple or in_array( ucfirst( $this->type ), $no ) )
|
||||
if ( $this->is_multiple or in_array( ucfirst( $this->type ), static::$cannotBeTitleFields ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -1261,7 +1391,7 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
|
||||
{
|
||||
$no = array();
|
||||
|
||||
if ( $this->is_multiple or in_array( ucfirst( $this->type ), $no ) )
|
||||
if ( $this->is_multiple or in_array( ucfirst( $this->type ), static::$cannotBeContentFields ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -1331,30 +1461,31 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
|
||||
$form->add( new \IPS\Helpers\Form\Translatable( 'field_title', NULL, TRUE, array( 'app' => 'core', 'key' => ( $this->id ? static::$langKey . '_' . $this->id : NULL ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Translatable( 'field_description', NULL, FALSE, array( 'app' => 'core', 'key' => ( $this->id ? static::$langKey . '_' . $this->id . '_desc' : NULL ) ) ) );
|
||||
|
||||
$displayDefaults = array( 'field_display_listing_json_badge', 'field_display_listing_json_badge_right', 'field_display_listing_json_custom', 'field_display_display_json_badge', 'field_display_display_json_custom' );
|
||||
$displayDefaults = array( 'field_display_listing_json_badge', 'field_display_listing_json_badge_right', 'field_display_listing_json_custom', 'field_display_display_json_badge', 'field_display_display_json_custom', 'field_display_display_json_where' );
|
||||
|
||||
$options = array_merge( array(
|
||||
'Address' => 'pf_type_Address',
|
||||
'Checkbox' => 'pf_type_Checkbox',
|
||||
'Address' => 'pf_type_Address',
|
||||
'Checkbox' => 'pf_type_Checkbox',
|
||||
'CheckboxSet' => 'pf_type_CheckboxSet',
|
||||
'Codemirror'=> 'pf_type_Codemirror',
|
||||
'Date' => 'pf_type_Date',
|
||||
'Editor' => 'pf_type_Editor',
|
||||
'Email' => 'pf_type_Email',
|
||||
'Member' => 'pf_type_Member',
|
||||
'Number' => 'pf_type_Number',
|
||||
'Password' => 'pf_type_Password',
|
||||
'Radio' => 'pf_type_Radio',
|
||||
'Select' => 'pf_type_Select',
|
||||
'Tel' => 'pf_type_Tel',
|
||||
'Text' => 'pf_type_Text',
|
||||
'TextArea' => 'pf_type_TextArea',
|
||||
'Upload' => 'pf_type_Upload',
|
||||
'Url' => 'pf_type_Url',
|
||||
'YesNo' => 'pf_type_YesNo',
|
||||
'Youtube' => 'pf_type_Youtube',
|
||||
'Spotify' => 'pf_type_Spotify',
|
||||
'Soundcloud'=> 'pf_type_Soundcloud',
|
||||
'Codemirror' => 'pf_type_Codemirror',
|
||||
'Item' => 'pf_type_Relational',
|
||||
'Date' => 'pf_type_Date',
|
||||
'Editor' => 'pf_type_Editor',
|
||||
'Email' => 'pf_type_Email',
|
||||
'Member' => 'pf_type_Member',
|
||||
'Number' => 'pf_type_Number',
|
||||
'Password' => 'pf_type_Password',
|
||||
'Radio' => 'pf_type_Radio',
|
||||
'Select' => 'pf_type_Select',
|
||||
'Tel' => 'pf_type_Tel',
|
||||
'Text' => 'pf_type_Text',
|
||||
'TextArea' => 'pf_type_TextArea',
|
||||
'Upload' => 'pf_type_Upload',
|
||||
'Url' => 'pf_type_Url',
|
||||
'YesNo' => 'pf_type_YesNo',
|
||||
'Youtube' => 'pf_type_Youtube',
|
||||
'Spotify' => 'pf_type_Spotify',
|
||||
'Soundcloud' => 'pf_type_Soundcloud',
|
||||
), static::$additionalFieldTypes );
|
||||
|
||||
$toggles = array(
|
||||
@@ -1365,6 +1496,7 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
|
||||
'Date' => array_merge( array( 'field_default_value', 'field_date_time_override' ), $displayDefaults ),
|
||||
'Editor' => array_merge( array( 'field_max_length', 'field_default_value', 'field_truncate' ), $displayDefaults ),
|
||||
'Email' => array_merge( array( 'field_max_length', 'field_default_value' ), $displayDefaults ),
|
||||
'Item' => array_merge( array( 'field_is_multiple', 'field_relational_db' ), $displayDefaults ),
|
||||
'Member' => array_merge( array( 'field_is_multiple' ), $displayDefaults ),
|
||||
'Number' => array_merge( array( 'field_default_value' ), $displayDefaults ),
|
||||
'Password' => array_merge( array( 'field_default_value' ), $displayDefaults ),
|
||||
@@ -1385,7 +1517,30 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
|
||||
{
|
||||
$toggles[ $k ] = isset( static::$additionalFieldToggles[ $k ] ) ? static::$additionalFieldToggles[ $k ] : array( 'pf_not_null' );
|
||||
}
|
||||
|
||||
|
||||
/* Title or content? */
|
||||
if ( $this->id )
|
||||
{
|
||||
$database = \IPS\cms\Databases::load( static::$customDatabaseId );
|
||||
|
||||
if ( $this->id == $database->field_title )
|
||||
{
|
||||
foreach( static::$cannotBeTitleFields as $type )
|
||||
{
|
||||
unset( $options[ $type ] );
|
||||
unset( $toggles[ $type ] );
|
||||
}
|
||||
}
|
||||
else if ( $this->id == $database->field_content )
|
||||
{
|
||||
foreach( static::$cannotBeContentFields as $type )
|
||||
{
|
||||
unset( $options[ $type ] );
|
||||
unset( $toggles[ $type ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ksort( $options );
|
||||
|
||||
if ( !$this->_new )
|
||||
@@ -1406,6 +1561,26 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
|
||||
'toggles' => $toggles
|
||||
) ) );
|
||||
|
||||
/* Relational specific */
|
||||
$databases = array();
|
||||
$disabled = array();
|
||||
foreach( \IPS\cms\Databases::databases() as $db )
|
||||
{
|
||||
if ( $db->page_id and $db->id !== static::$customDatabaseId )
|
||||
{
|
||||
$databases[ $db->id ] = $db->_title;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! count( $databases ) )
|
||||
{
|
||||
$databases[0] = \IPS\Member::loggedIn()->language()->addToStack('cms_relational_field_no_dbs');
|
||||
$disabled[] = 0;
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'field_relational_db', ( isset( $this->extra['database'] ) ? $this->extra['database'] : NULL ), FALSE, array( 'options' => $databases, 'disabled' => $disabled ), NULL, NULL, NULL, 'field_relational_db' ) );
|
||||
|
||||
/* Upload specific */
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'field_upload_is_multiple', $this->id ? $this->is_multiple : 0, FALSE, array( ), NULL, NULL, NULL, 'field_upload_is_multiple' ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'field_upload_is_image', $this->id ? ( ( isset( $this->extra['type'] ) and $this->extra['type'] == 'image' ) ? 'yes' : 'no' ) : 'yes', TRUE, array(
|
||||
@@ -1592,6 +1767,7 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
|
||||
$listingToggles[ $id ] = array( 'field_display_listing_json_badge_right' );
|
||||
}
|
||||
|
||||
$displayOptions['simple'] = $listingOptions['simple'] = \IPS\Theme::i()->getTemplate( 'records', 'cms', 'global' )->fieldDefault( \IPS\Member::loggedIn()->language()->addToStack('cms_badge_label'), \IPS\Member::loggedIn()->language()->addToStack('cms_badge_value' ) );
|
||||
$displayOptions['custom'] = $listingOptions['custom'] = \IPS\Member::loggedIn()->language()->addToStack('field_display_custom');
|
||||
$displayOptions['none'] = $listingOptions['none'] = \IPS\Member::loggedIn()->language()->addToStack('field_display_none');
|
||||
|
||||
@@ -1659,6 +1835,9 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
|
||||
|
||||
}, NULL, NULL, 'field_display_display_json_custom' ) );
|
||||
|
||||
/* Display where? */
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'field_display_display_json_where', ( isset( $displayJson['display']['where'] ) ? $displayJson['display']['where'] : 'top' ), FALSE, array( 'options' => array( 'top' => 'cms_field_display_top', 'bottom' => 'cms_field_display_bottom' ) ), NULL, NULL, NULL, 'field_display_display_json_where' ) );
|
||||
|
||||
/* Media display */
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'media_display_display_method', $mediaDisplayDefault, FALSE, array( 'options' => $mediaListingOptions ), NULL, NULL, NULL, 'media_display_display_method' ) );
|
||||
|
||||
@@ -1723,7 +1902,6 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
|
||||
$values['field_extra'] = $extra;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $values['field_type'] === 'Select' )
|
||||
{
|
||||
$columnDefinition['type'] = 'TEXT';
|
||||
@@ -1817,15 +1995,26 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
|
||||
{
|
||||
\IPS\Db::i()->addColumn( static::$contentDatabaseTable, $columnDefinition );
|
||||
|
||||
if ( $values['field_type'] != 'Upload' )
|
||||
if ( ! empty( $values['field_filter'] ) and $values['field_type'] != 'Upload' )
|
||||
{
|
||||
if ( $columnDefinition['type'] == 'TEXT' )
|
||||
try
|
||||
{
|
||||
\IPS\Db::i()->addIndex( static::$contentDatabaseTable, array( 'type' => 'fulltext', 'name' => "field_{$this->id}", 'columns' => array( "field_{$this->id}" ) ) );
|
||||
if ( $columnDefinition['type'] == 'TEXT' )
|
||||
{
|
||||
\IPS\Db::i()->addIndex( static::$contentDatabaseTable, array( 'type' => 'fulltext', 'name' => "field_{$this->id}", 'columns' => array( "field_{$this->id}" ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Db::i()->addIndex( static::$contentDatabaseTable, array( 'type' => 'key', 'name' => "field_{$this->id}", 'columns' => array( "field_{$this->id}" ) ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
catch( \IPS\Db\Exception $e )
|
||||
{
|
||||
\IPS\Db::i()->addIndex( static::$contentDatabaseTable, array( 'type' => 'key', 'name' => "field_{$this->id}", 'columns' => array( "field_{$this->id}" ) ) );
|
||||
if ( $e->getCode() !== 1069 )
|
||||
{
|
||||
# 1069: MyISAM can only have 64 indexes per table. This should be really rare though so we silently ignore it.
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1837,28 +2026,60 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
|
||||
\IPS\Db::i()->dropIndex( static::$contentDatabaseTable, "field_{$this->id}" );
|
||||
\IPS\Db::i()->dropColumn( static::$contentDatabaseTable, "field_{$this->id}" );
|
||||
}
|
||||
catch ( \IPS\Db\Exception $e )
|
||||
{
|
||||
|
||||
}
|
||||
catch ( \IPS\Db\Exception $e ) { }
|
||||
|
||||
\IPS\Db::i()->addColumn( static::$contentDatabaseTable, $columnDefinition );
|
||||
|
||||
if ( $values['field_type'] != 'Upload' )
|
||||
{
|
||||
if ( $columnDefinition['type'] == 'TEXT' )
|
||||
try
|
||||
{
|
||||
\IPS\Db::i()->addIndex( static::$contentDatabaseTable, array( 'type' => 'fulltext', 'name' => "field_{$this->id}", 'columns' => array( "field_{$this->id}" ) ) );
|
||||
if ( $columnDefinition['type'] == 'TEXT' )
|
||||
{
|
||||
\IPS\Db::i()->addIndex( static::$contentDatabaseTable, array( 'type' => 'fulltext', 'name' => "field_{$this->id}", 'columns' => array( "field_{$this->id}" ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Db::i()->addIndex( static::$contentDatabaseTable, array( 'type' => 'key', 'name' => "field_{$this->id}", 'columns' => array( "field_{$this->id}" ) ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
catch( \IPS\Db\Exception $e )
|
||||
{
|
||||
\IPS\Db::i()->addIndex( static::$contentDatabaseTable, array( 'type' => 'key', 'name' => "field_{$this->id}", 'columns' => array( "field_{$this->id}" ) ) );
|
||||
if ( $e->getCode() !== 1069 )
|
||||
{
|
||||
# 1069: MyISAM can only have 64 indexes per table. This should be really rare though so we silently ignore it.
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif ( isset( static::$contentDatabaseTable ) AND isset( $columnDefinition ) )
|
||||
{
|
||||
\IPS\Db::i()->dropIndex( static::$contentDatabaseTable, "field_{$this->id}" );
|
||||
\IPS\Db::i()->changeColumn( static::$contentDatabaseTable, "field_{$this->id}", $columnDefinition );
|
||||
|
||||
if ( $values['field_filter'] and $values['field_type'] != 'Upload' )
|
||||
{
|
||||
try
|
||||
{
|
||||
if ( $columnDefinition['type'] == 'TEXT' )
|
||||
{
|
||||
\IPS\Db::i()->addIndex( static::$contentDatabaseTable, array( 'type' => 'fulltext', 'name' => "field_{$this->id}", 'columns' => array( "field_{$this->id}" ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Db::i()->addIndex( static::$contentDatabaseTable, array( 'type' => 'key', 'name' => "field_{$this->id}", 'columns' => array( "field_{$this->id}" ) ) );
|
||||
}
|
||||
}
|
||||
catch( \IPS\Db\Exception $e )
|
||||
{
|
||||
if ( $e->getCode() !== 1069 )
|
||||
{
|
||||
# 1069: MyISAM can only have 64 indexes per table. This should be really rare though so we silently ignore it.
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Save the name and desctipn */
|
||||
@@ -1998,6 +2219,11 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
|
||||
{
|
||||
$displayJson['display']['method'] = $values['field_display_display_json_badge'];
|
||||
}
|
||||
|
||||
if ( isset( $values['field_display_display_json_where'] ) )
|
||||
{
|
||||
$displayJson['display']['where'] = $values['field_display_display_json_where'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2041,13 +2267,24 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
|
||||
}
|
||||
}
|
||||
|
||||
/* Special relational stuff */
|
||||
if ( isset( $values['field_type'] ) AND $values['field_type'] === 'Item' )
|
||||
{
|
||||
if ( array_key_exists( 'field_relational_db', $values ) and empty( $values['field_relational_db'] ) )
|
||||
{
|
||||
throw new \LogicException( \IPS\Member::loggedIn()->language()->addToStack('cms_relational_field_no_db_selected') );
|
||||
}
|
||||
|
||||
$values['extra'] = array( 'database' => $values['field_relational_db'] );
|
||||
}
|
||||
|
||||
if ( ! $this->new AND isset( $values['field_default_update_existing'] ) AND $values['field_default_update_existing'] and $values['field_default_value'] !== $this->default_value )
|
||||
{
|
||||
$this->_updateDefaultValue = TRUE;
|
||||
$this->_oldDefaultValue = $this->default_value;
|
||||
}
|
||||
|
||||
foreach( array( 'field_upload_is_multiple', 'field_default_update_existing', 'field_date_time_override', 'field_date_timezone', 'field_upload_is_image', 'field_image_size', 'field_title', 'field_display_display_json_badge', 'field_display_display_json_custom', 'field_display_listing_json_badge', 'field_display_listing_json_custom', 'field_display_listing_json_badge_right', 'media_display_listing_method', 'media_display_display_method', 'field_show_map_listing', 'field_show_map_listing_dims', 'field_show_map_display', 'field_show_map_display_dims' ) as $field )
|
||||
foreach( array( 'field_relational_db', 'field_upload_is_multiple', 'field_default_update_existing', 'field_date_time_override', 'field_date_timezone', 'field_upload_is_image', 'field_image_size', 'field_title', 'field_display_display_json_badge', 'field_display_display_json_custom', 'field_display_listing_json_badge', 'field_display_listing_json_custom', 'field_display_listing_json_badge_right', 'media_display_listing_method', 'media_display_display_method', 'field_show_map_listing', 'field_show_map_listing_dims', 'field_show_map_display', 'field_show_map_display_dims', 'field_display_display_json_where' ) as $field )
|
||||
{
|
||||
if ( array_key_exists( $field, $values ) )
|
||||
{
|
||||
@@ -2086,7 +2323,7 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
|
||||
*/
|
||||
protected function canKeepValueOnChange( $newType )
|
||||
{
|
||||
$custom = array( 'Youtube', 'Spotify', 'Soundcloud');
|
||||
$custom = array( 'Youtube', 'Spotify', 'Soundcloud', 'Relational' );
|
||||
|
||||
if ( ! in_array( $this->type, $custom ) )
|
||||
{
|
||||
@@ -2131,15 +2368,15 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
|
||||
{
|
||||
unset( \IPS\Data\Store::i()->$functionName );
|
||||
}
|
||||
|
||||
$key = 'cms_fieldids_' . static::$customDatabaseId;
|
||||
|
||||
if ( isset( \IPS\Data\Store::i()->$key ) )
|
||||
{
|
||||
unset( \IPS\Data\Store::i()->$key );
|
||||
}
|
||||
|
||||
if ( $this->_new )
|
||||
{
|
||||
parent::save();
|
||||
}
|
||||
else
|
||||
{
|
||||
parent::save();
|
||||
}
|
||||
parent::save();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2152,7 +2389,14 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
|
||||
{
|
||||
static::$contentDatabaseTable = 'cms_custom_database_' . static::$customDatabaseId;
|
||||
static::$cache = array();
|
||||
|
||||
|
||||
$key = 'cms_fieldids_' . static::$customDatabaseId;
|
||||
|
||||
if ( isset( \IPS\Data\Store::i()->$key ) )
|
||||
{
|
||||
unset( \IPS\Data\Store::i()->$key );
|
||||
}
|
||||
|
||||
parent::delete();
|
||||
|
||||
if( $skipDrop === TRUE )
|
||||
@@ -2302,9 +2546,28 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
|
||||
|
||||
if ( $this->is_multiple and ! is_array( $value ) and mb_stristr( $value, ',' ) )
|
||||
{
|
||||
$value = explode( ',', $value );
|
||||
$exp = explode( ',', $value );
|
||||
$value = array();
|
||||
foreach( $exp as $val )
|
||||
{
|
||||
if ( is_numeric( $val ) and intval( $val ) == $val )
|
||||
{
|
||||
$value[] = intval( $val );
|
||||
}
|
||||
else
|
||||
{
|
||||
$value[] = $val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if ( is_numeric( $value ) and intval( $value ) == $value )
|
||||
{
|
||||
$value = intval( $value );
|
||||
}
|
||||
}
|
||||
|
||||
$json = $this->extra;
|
||||
$options['options'] = ( $json ) ? $json : array();
|
||||
break;
|
||||
@@ -2356,6 +2619,10 @@ class _Fields extends \IPS\CustomField implements \IPS\Node\Permissions
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case 'Item':
|
||||
$options['maxItems'] = ( $this->is_multiple ) ? NULL : 1;
|
||||
$options['class'] = '\IPS\cms\Records' . $this->extra['database'];
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,341 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Folder Model
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @since 07 July 2015
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\cms\Media;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Folder Model
|
||||
*/
|
||||
class _Folder extends \IPS\Node\Model
|
||||
{
|
||||
/**
|
||||
* Munge different record types
|
||||
*
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function munge()
|
||||
{
|
||||
$rows = array();
|
||||
$args = func_get_args();
|
||||
|
||||
foreach( $args as $arg )
|
||||
{
|
||||
foreach( $arg as $id => $obj )
|
||||
{
|
||||
$rows[ $obj->getSortableName() . '_' . $obj::$databaseTable . '_' . $obj->id ] = $obj;
|
||||
}
|
||||
}
|
||||
|
||||
ksort( $rows );
|
||||
|
||||
return $rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Multiton Store
|
||||
*/
|
||||
protected static $multitons;
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Table
|
||||
*/
|
||||
public static $databaseTable = 'cms_media_folders';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Prefix
|
||||
*/
|
||||
public static $databasePrefix = 'media_folder_';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] ID Database Column
|
||||
*/
|
||||
public static $databaseColumnId = 'id';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database ID Fields
|
||||
*/
|
||||
protected static $databaseIdFields = array('media_folder_path');
|
||||
|
||||
/**
|
||||
* @brief [Node] Parent ID Database Column
|
||||
*/
|
||||
public static $databaseColumnParent = 'parent';
|
||||
|
||||
/**
|
||||
* @brief [Node] Parent ID Root Value
|
||||
* @note This normally doesn't need changing though some legacy areas use -1 to indicate a root node
|
||||
*/
|
||||
public static $databaseColumnParentRootValue = 0;
|
||||
|
||||
/**
|
||||
* @brief [Node] Order Database Column
|
||||
*/
|
||||
public static $databaseColumnOrder = 'path';
|
||||
|
||||
/**
|
||||
* @brief [Node] Node Title
|
||||
*/
|
||||
public static $nodeTitle = 'folder';
|
||||
|
||||
/**
|
||||
* @brief [Node] Subnode class
|
||||
*/
|
||||
public static $subnodeClass = 'IPS\cms\Media';
|
||||
|
||||
/**
|
||||
* @brief [Node] Show forms modally?
|
||||
*/
|
||||
public static $modalForms = TRUE;
|
||||
|
||||
protected static $restrictions = array(
|
||||
'app' => 'cms',
|
||||
'module' => 'pages',
|
||||
'all' => 'media_manage',
|
||||
'prefix' => 'media_'
|
||||
);
|
||||
|
||||
/**
|
||||
* [Node] Get Title
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
protected function get__title()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sortable name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSortableName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Get buttons to display in tree
|
||||
* Example code explains return value
|
||||
* @endcode
|
||||
* @param string $url Base URL
|
||||
* @param bool $subnode Is this a subnode?
|
||||
* @return array
|
||||
*/
|
||||
public function getButtons( $url, $subnode=FALSE )
|
||||
{
|
||||
$buttons = parent::getButtons( $url, $subnode );
|
||||
$return = array();
|
||||
|
||||
if ( isset( $buttons['copy'] ) )
|
||||
{
|
||||
unset( $buttons['copy'] );
|
||||
}
|
||||
|
||||
if ( isset( $buttons['add'] ) )
|
||||
{
|
||||
$buttons['add']['icon'] = 'folder-open';
|
||||
$buttons['add']['title'] = 'cms_add_media_folder';
|
||||
$buttons['add']['data'] = array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('cms_add_media_folder') );
|
||||
$buttons['add']['link'] = $url->setQueryString( array( 'subnode' => 0, 'do' => 'form', 'parent' => $this->_id ) );
|
||||
|
||||
$buttons['add_page'] = array(
|
||||
'icon' => 'plus-circle',
|
||||
'title' => 'cms_add_media',
|
||||
'link' => $url->setQueryString( array( 'subnode' => 1, 'do' => 'add', 'parent' => $this->_id ) ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('cms_add_media') )
|
||||
);
|
||||
}
|
||||
|
||||
/* Re-arrange */
|
||||
if ( isset( $buttons['edit'] ) )
|
||||
{
|
||||
$return['edit'] = $buttons['edit'];
|
||||
}
|
||||
|
||||
if ( isset( $buttons['add_page'] ) )
|
||||
{
|
||||
$return['add_page'] = $buttons['add_page'];
|
||||
}
|
||||
|
||||
if ( isset( $buttons['add'] ) )
|
||||
{
|
||||
$return['add'] = $buttons['add'];
|
||||
}
|
||||
|
||||
if ( isset( $buttons['delete'] ) )
|
||||
{
|
||||
$return['delete'] = $buttons['delete'];
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Add/Edit Form
|
||||
*
|
||||
* @param \IPS\Helpers\Form $form The form
|
||||
* @return void
|
||||
*/
|
||||
public function form( &$form )
|
||||
{
|
||||
/* Build form */
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'media_folder_name', $this->id ? $this->name : '', TRUE, array( 'maxLength' => 64 ), function( $val )
|
||||
{
|
||||
try
|
||||
{
|
||||
$test = \IPS\cms\Media\Folder::load( \IPS\Http\Url::seoTitle( $val ), 'media_folder_name' );
|
||||
|
||||
if ( ! empty( \IPS\Request::i()->id ) and $test->id != \IPS\Request::i()->id )
|
||||
{
|
||||
throw new \InvalidArgumentException('content_folder_name_in_use');
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
}
|
||||
} ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'media_folder_parent', $this->parent ? $this->parent : 0, FALSE, array(
|
||||
'class' => '\IPS\cms\Media\Folder',
|
||||
'zeroVal' => 'node_no_parent',
|
||||
'permissionCheck' => function( $node )
|
||||
{
|
||||
if ( ! isset( \IPS\Request::i()->id ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( ! isset( \IPS\Request::i()->parent ) )
|
||||
{
|
||||
return $node->id != \IPS\Request::i()->id;
|
||||
}
|
||||
}
|
||||
) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Original parent ID
|
||||
*/
|
||||
protected $origParentId;
|
||||
|
||||
/**
|
||||
* @brief Original parent Name
|
||||
*/
|
||||
protected $origName;
|
||||
|
||||
/**
|
||||
* [Node] Format form values from add/edit form for save
|
||||
*
|
||||
* @param array $values Values from the form
|
||||
* @return array
|
||||
*/
|
||||
public function formatFormValues( $values )
|
||||
{
|
||||
if ( ! $this->id )
|
||||
{
|
||||
$this->save();
|
||||
}
|
||||
|
||||
$this->origParentId = $this->parent;
|
||||
$this->origName = $this->name;
|
||||
|
||||
if ( isset( $values['media_folder_parent'] ) AND ( ! empty( $values['media_folder_parent'] ) OR $values['media_folder_parent'] === 0 ) )
|
||||
{
|
||||
$values['parent'] = ( $values['media_folder_parent'] === 0 ) ? 0 : $values['media_folder_parent']->id;
|
||||
unset( $values['media_folder_parent'] );
|
||||
}
|
||||
|
||||
if( isset( $values['media_folder_name'] ) )
|
||||
{
|
||||
$values['name'] = \IPS\Http\Url::seoTitle( $values['media_folder_name'] );
|
||||
unset( $values['media_folder_name'] );
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Perform actions after saving the form
|
||||
*
|
||||
* @param array $values Values from the form
|
||||
* @return void
|
||||
*/
|
||||
public function postSaveForm( $values )
|
||||
{
|
||||
if ( $this->origParentId !== $values['parent'] OR $this->origName !== $values['name'] )
|
||||
{
|
||||
$this->resetPath( true );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the stored path
|
||||
*
|
||||
* @param boolean $recursivelyCheck Recursively reset up and down the tree
|
||||
* @return void
|
||||
*/
|
||||
public function resetPath( $recursivelyCheck=true )
|
||||
{
|
||||
$path = array();
|
||||
|
||||
foreach( $this->parents() as $obj )
|
||||
{
|
||||
$path[] = $obj->name;
|
||||
}
|
||||
|
||||
$this->path = ( count( $path ) ) ? implode( '/', $path ) . '/' . $this->name : $this->name;
|
||||
|
||||
/* Save path update */
|
||||
parent::save();
|
||||
|
||||
/* Update media */
|
||||
\IPS\cms\Media::resetPath( $this->id );
|
||||
|
||||
if ( $recursivelyCheck === true )
|
||||
{
|
||||
/* Fix children */
|
||||
foreach( $this->children( NULL, NULL, FALSE ) as $child )
|
||||
{
|
||||
$child->resetPath( false );
|
||||
$child->_recursivelyResetChildPaths();
|
||||
}
|
||||
|
||||
/* Fix parents */
|
||||
foreach( $this->parents() as $parent )
|
||||
{
|
||||
$parent->resetPath( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recurse through the node tree to reset kids
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function _recursivelyResetChildPaths()
|
||||
{
|
||||
foreach( $this->children( NULL, NULL, FALSE ) as $child )
|
||||
{
|
||||
$child->resetPath( false );
|
||||
$child->_recursivelyResetChildPaths();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,568 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Media Model
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @since 15 Jan 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\cms;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Media Model
|
||||
*/
|
||||
class _Media extends \IPS\Node\Model
|
||||
{
|
||||
/**
|
||||
* @brief [ActiveRecord] Multiton Store
|
||||
*/
|
||||
protected static $multitons;
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Table
|
||||
*/
|
||||
public static $databaseTable = 'cms_media';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Prefix
|
||||
*/
|
||||
public static $databasePrefix = 'media_';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] ID Database Column
|
||||
*/
|
||||
public static $databaseColumnId = 'id';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database ID Fields
|
||||
*/
|
||||
protected static $databaseIdFields = array('media_full_path');
|
||||
|
||||
/**
|
||||
* @brief [Node] Parent Node ID Database Column
|
||||
*/
|
||||
public static $parentNodeColumnId = 'parent';
|
||||
|
||||
/**
|
||||
* @brief [Node] Parent Node Class
|
||||
*/
|
||||
public static $parentNodeClass = 'IPS\cms\Media\Folder';
|
||||
|
||||
/**
|
||||
* @brief [Node] Parent ID Database Column
|
||||
*/
|
||||
public static $databaseColumnOrder = 'filename';
|
||||
|
||||
/**
|
||||
* @brief [Node] Show forms modally?
|
||||
*/
|
||||
public static $modalForms = TRUE;
|
||||
|
||||
/**
|
||||
* @brief [Node] Title
|
||||
*/
|
||||
public static $nodeTitle = 'page';
|
||||
|
||||
/**
|
||||
* @brief [Node] ACP Restrictions
|
||||
* @code
|
||||
array(
|
||||
'app' => 'core', // The application key which holds the restrictrions
|
||||
'module' => 'foo', // The module key which holds the restrictions
|
||||
'map' => array( // [Optional] The key for each restriction - can alternatively use "prefix"
|
||||
'add' => 'foo_add',
|
||||
'edit' => 'foo_edit',
|
||||
'permissions' => 'foo_perms',
|
||||
'delete' => 'foo_delete'
|
||||
),
|
||||
'all' => 'foo_manage', // [Optional] The key to use for any restriction not provided in the map (only needed if not providing all 4)
|
||||
'prefix' => 'foo_', // [Optional] Rather than specifying each key in the map, you can specify a prefix, and it will automatically look for restrictions with the key "[prefix]_add/edit/permissions/delete"
|
||||
* @endcode
|
||||
*/
|
||||
protected static $restrictions = array(
|
||||
'app' => 'cms',
|
||||
'module' => 'pages',
|
||||
'prefix' => 'media_'
|
||||
);
|
||||
|
||||
/**
|
||||
* Set Default Values
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setDefaultValues()
|
||||
{
|
||||
$this->parent = 0;
|
||||
$this->full_path = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets a media path
|
||||
*
|
||||
* @param int $folderId Folder ID to reset
|
||||
* @return void
|
||||
*/
|
||||
public static function resetPath( $folderId )
|
||||
{
|
||||
try
|
||||
{
|
||||
$path = \IPS\cms\Media\Folder::load( $folderId )->path;
|
||||
}
|
||||
catch ( \OutOfRangeException $ex )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
|
||||
$children = static::getChildren( $folderId );
|
||||
|
||||
foreach( $children as $id => $obj )
|
||||
{
|
||||
$obj->setFullPath( $path );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all children of a specific folder.
|
||||
*
|
||||
* @param INT $folderId Folder ID to fetch children from
|
||||
* @return array
|
||||
*/
|
||||
public static function getChildren( $folderId=0 )
|
||||
{
|
||||
$children = array();
|
||||
foreach( \IPS\Db::i()->select( '*', static::$databaseTable, array( 'media_parent=?', intval( $folderId ) ), 'media_filename ASC' ) as $child )
|
||||
{
|
||||
$children[ $child[ static::$databasePrefix . static::$databaseColumnId ] ] = static::load( $child[ static::$databasePrefix . static::$databaseColumnId ] );
|
||||
}
|
||||
|
||||
return $children;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete media by file ids
|
||||
*
|
||||
* @param array $ids Array of IDs to remove
|
||||
* @return void
|
||||
*/
|
||||
public static function deleteByFileIds( $ids=array() )
|
||||
{
|
||||
foreach( $ids as $id )
|
||||
{
|
||||
try
|
||||
{
|
||||
static::load( $id )->delete();
|
||||
}
|
||||
catch( \Exception $ex ) { }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get URL
|
||||
*
|
||||
* @return \IPS\Http\Url object
|
||||
*/
|
||||
public function url()
|
||||
{
|
||||
if ( \IPS\Theme::designersModeEnabled() )
|
||||
{
|
||||
return \IPS\Settings::i()->base_url . 'themes/cms/media/' . $this->full_path;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (string)\IPS\File::get( 'cms_Media', $this->file_object )->url;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [ActiveRecord] Delete Record
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
try
|
||||
{
|
||||
if ( $this->file_object )
|
||||
{
|
||||
\IPS\File::get( 'cms_Media', $this->file_object )->delete();
|
||||
}
|
||||
}
|
||||
catch( \Exception $ex ) { }
|
||||
|
||||
parent::delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Get buttons to display in tree
|
||||
* Example code explains return value
|
||||
* @endcode
|
||||
* @param string $url Base URL
|
||||
* @param bool $subnode Is this a subnode?
|
||||
* @return array
|
||||
*/
|
||||
public function getButtons( $url, $subnode=FALSE )
|
||||
{
|
||||
$buttons = parent::getButtons( $url, $subnode );
|
||||
$delete = NULL;
|
||||
|
||||
if ( isset( $buttons['add' ] ) )
|
||||
{
|
||||
unset( $buttons['add'] );
|
||||
}
|
||||
|
||||
if ( isset( $buttons['delete'] ) )
|
||||
{
|
||||
$delete = $buttons['delete'];
|
||||
unset( $buttons['delete'] );
|
||||
}
|
||||
|
||||
if ( isset( $buttons['copy' ] ) )
|
||||
{
|
||||
unset( $buttons['copy'] );
|
||||
}
|
||||
|
||||
$buttons['key'] = array(
|
||||
'icon' => 'file-code-o',
|
||||
'title' => 'cms_media_key',
|
||||
'link' => \IPS\Http\Url::internal( 'app=cms&module=pages&controller=media&do=key&id=' . $this->id ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('cms_media_key') )
|
||||
);
|
||||
|
||||
if ( $this->is_image )
|
||||
{
|
||||
$buttons['preview'] = array(
|
||||
'icon' => 'search',
|
||||
'title' => 'cms_media_preview',
|
||||
'link' => \IPS\Http\Url::internal( 'app=cms&module=pages&controller=media&do=preview&id=' . $this->id ),
|
||||
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('cms_media_preview') )
|
||||
);
|
||||
}
|
||||
|
||||
if ( $delete )
|
||||
{
|
||||
$buttons['delete'] = $delete;
|
||||
}
|
||||
|
||||
return $buttons;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Add/Edit Form
|
||||
*
|
||||
* @note This is not used currently. See \IPS\cms\modules\admin\media.php upload()
|
||||
* @param \IPS\Helpers\Form $form The form
|
||||
* @return void
|
||||
*/
|
||||
public function form( &$form )
|
||||
{
|
||||
/* Build form */
|
||||
$form->add( new \IPS\Helpers\Form\Upload( 'media_filename', ( ( $this->filename ) ? \IPS\File::get( 'cms_Media', $this->file_object ) : NULL ), FALSE, array( 'obscure' => FALSE, 'maxFileSize' => 5, 'storageExtension' => 'core_Theme', 'storageContainer' => 'pages_media' ), NULL, NULL, NULL, 'media_filename' ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'media_parent', $this->parent ? $this->parent : 0, FALSE, array(
|
||||
'class' => '\IPS\cms\Media\Folder',
|
||||
'zeroVal' => 'node_no_parent'
|
||||
) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Format form values from add/edit form for save
|
||||
*
|
||||
* @note This is not used currently. See \IPS\cms\modules\admin\media.php upload()
|
||||
* @param array $values Values from the form
|
||||
* @return array
|
||||
*/
|
||||
public function formatFormValues( $values )
|
||||
{
|
||||
if ( isset( $values['media_parent'] ) AND ( ! empty( $values['media_parent'] ) OR $values['media_parent'] === 0 ) )
|
||||
{
|
||||
$values['parent'] = ( $values['media_parent'] === 0 ) ? 0 : $values['media_parent']->id;
|
||||
unset( $values['media_parent'] );
|
||||
}
|
||||
|
||||
if ( isset( $values['media_filename'] ) )
|
||||
{
|
||||
$filename = $values['media_filename']->originalFilename;
|
||||
|
||||
if ( ! $this->_new and $this->file_object )
|
||||
{
|
||||
$prefix = $this->parent . '_';
|
||||
|
||||
if ( mb_strstr( $filename, $prefix ) )
|
||||
{
|
||||
$filename = mb_substr( $filename, mb_strlen( $prefix ) );
|
||||
}
|
||||
}
|
||||
|
||||
$values['filename'] = $filename;
|
||||
$values['filename_stored'] = $values['parent'] . '_' . $values['filename'];
|
||||
$values['is_image'] = $values['media_filename']->isImage();
|
||||
|
||||
/* We need to rename it */
|
||||
try
|
||||
{
|
||||
$values['media_filename']->delete();
|
||||
}
|
||||
catch( \Exception $ex ) { }
|
||||
|
||||
$values['file_object'] = (string) \IPS\File::create( 'cms_Media', $values['filename_stored'], $values['media_filename']->contents(), 'pages_media', TRUE, NULL, FALSE );
|
||||
|
||||
unset( $values['media_filename'] );
|
||||
}
|
||||
|
||||
if ( $this->_new )
|
||||
{
|
||||
$values['added'] = time();
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Perform actions after saving the form
|
||||
*
|
||||
* @note This is not used currently. See \IPS\cms\modules\admin\media.php upload()
|
||||
* @param array $values Values from the form
|
||||
* @return void
|
||||
*/
|
||||
public function postSaveForm( $values )
|
||||
{
|
||||
$this->setFullPath( ( $this->parent ? \IPS\cms\Media\Folder::load( $this->parent )->path : '' ) );
|
||||
$this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sortable name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSortableName()
|
||||
{
|
||||
return $this->full_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets a folder path
|
||||
*
|
||||
* @param string $path Path to reset
|
||||
* @return void
|
||||
*/
|
||||
public function setFullPath( $path )
|
||||
{
|
||||
$this->full_path = trim( $path . '/' . $this->filename, '/' );
|
||||
$this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write media to disk for designer's mode
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function exportDesignersModeMedia()
|
||||
{
|
||||
foreach( \IPS\Db::i()->select( '*', 'cms_media' ) as $media )
|
||||
{
|
||||
/* We could use recursive mode but it wouldn't correctly chmod the intermediate dirs */
|
||||
$bits = explode( '/', "/themes/cms/media/" . $media['media_full_path'] );
|
||||
$dir = '';
|
||||
|
||||
$filename = array_pop( $bits );
|
||||
|
||||
foreach( $bits as $part )
|
||||
{
|
||||
$dir .= $part . '/';
|
||||
|
||||
if ( ! is_dir( \IPS\ROOT_PATH . '/' . trim( $dir, '/' ) ) )
|
||||
{
|
||||
mkdir( \IPS\ROOT_PATH . '/' . trim( $dir, '/' ), \IPS\IPS_FOLDER_PERMISSION );
|
||||
chmod( \IPS\ROOT_PATH . '/' . trim( $dir, '/' ), \IPS\IPS_FOLDER_PERMISSION );
|
||||
}
|
||||
}
|
||||
|
||||
\file_put_contents( \IPS\ROOT_PATH . '/' . trim( $dir, '/' ) . '/' . $filename, \IPS\File::get( 'cms_Media', $media['media_file_object'] )->contents() );
|
||||
@chmod( \IPS\ROOT_PATH . '/' . trim( $dir, '/' ) . '/' . $filename, \IPS\IPS_FILE_PERMISSION );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes folders that are empty
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function removeEmptyFolders()
|
||||
{
|
||||
$folders = iterator_to_array( \IPS\Db::i()->select( 'DISTINCT(media_parent)', 'cms_media', array( 'media_parent > 0' ) ) );
|
||||
$allFolders = iterator_to_array( \IPS\Db::i()->select( '*', 'cms_media_folders' )->setKeyField( 'media_folder_id' ) );
|
||||
|
||||
foreach( $folders as $id )
|
||||
{
|
||||
if ( isset( $allFolders[ $id ] ) )
|
||||
{
|
||||
$currentParent = $allFolders[ $id ]['media_folder_parent'];
|
||||
$try = 0;
|
||||
while( $currentParent )
|
||||
{
|
||||
if ( $try++ > 50 )
|
||||
{
|
||||
/* Prevent broken associations from preventing execution */
|
||||
break;
|
||||
}
|
||||
|
||||
if ( ! in_array( $currentParent, $folders ) )
|
||||
{
|
||||
$folders[] = $currentParent;
|
||||
}
|
||||
|
||||
$currentParent = $allFolders[ $currentParent ]['media_folder_parent'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Db::i()->delete( 'cms_media_folders', array( \IPS\Db::i()->in( 'media_folder_id', array_values( $folders ), TRUE ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Import media from disk for designer's mode
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function importDesignersModeMedia()
|
||||
{
|
||||
$path = \IPS\ROOT_PATH . '/themes/cms/media';
|
||||
$seen = array();
|
||||
|
||||
if ( is_dir( $path ) )
|
||||
{
|
||||
static::importDesignersModeMediaRecurse( $seen, $path );
|
||||
}
|
||||
|
||||
\IPS\Db::i()->delete( 'cms_media', array( \IPS\Db::i()->in( 'media_id', $seen, TRUE ) ) );
|
||||
static::removeEmptyFolders();
|
||||
}
|
||||
|
||||
/**
|
||||
* Import media from disk for designer's mode recursive method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function importDesignersModeMediaRecurse( &$seen, $path )
|
||||
{
|
||||
if ( is_dir( $path ) )
|
||||
{
|
||||
foreach ( new \DirectoryIterator( $path ) as $dir )
|
||||
{
|
||||
if ( $dir->isDot() || mb_substr( $dir->getFilename(), 0, 1 ) === '.' )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( $dir->isDir() )
|
||||
{
|
||||
static::importDesignersModeMediaRecurse( $seen, $path . '/' . $dir->getFilename() );
|
||||
}
|
||||
else
|
||||
{
|
||||
$contents = \file_get_contents( $dir->getRealPath() );
|
||||
|
||||
/* Create */
|
||||
$seen[] = static::createMedia( trim( str_replace( \IPS\ROOT_PATH . '/themes/cms/media', '', $dir->getRealPath() ), '/' ), $contents );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new media file from a disk file. If the file exists and is unchanged, it will not be updated
|
||||
*
|
||||
* @param string $path File path (/folder/file.txt)
|
||||
* @param string $contents File contents
|
||||
* @return int ID of existing media or of new media
|
||||
*/
|
||||
public static function createMedia( $path, $contents )
|
||||
{
|
||||
try
|
||||
{
|
||||
$test = static::load( $path, 'media_full_path' );
|
||||
|
||||
$test->file_object = \IPS\File::create( 'cms_Media', $test->filename_stored, $contents, 'pages_media', TRUE, NULL, FALSE );
|
||||
$test->save();
|
||||
|
||||
return $test->id;
|
||||
}
|
||||
catch( \RuntimeException $ex )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\File::get( 'cms_Media', $path );
|
||||
}
|
||||
catch( \Exception $x )
|
||||
{
|
||||
/* File doesn't exist already */
|
||||
throw $ex;
|
||||
}
|
||||
}
|
||||
catch( \OutOfRangeException $ex )
|
||||
{
|
||||
/* It doesn't exist */
|
||||
$exploded = explode( '/', $path );
|
||||
$filename = array_pop( $exploded );
|
||||
$folderId = 0;
|
||||
|
||||
if ( count( $exploded ) )
|
||||
{
|
||||
$testDir = trim( implode( '/', $exploded ), '/' );
|
||||
try
|
||||
{
|
||||
$test = \IPS\cms\Media\Folder::load( $testDir, 'media_folder_path' );
|
||||
|
||||
/* Yep */
|
||||
$folderId = $test->id;
|
||||
}
|
||||
catch( \OutOfRangeException $ex )
|
||||
{
|
||||
$testDir = '';
|
||||
foreach( $exploded as $dir )
|
||||
{
|
||||
$testDir = trim( $testDir . '/' . $dir, '/' );
|
||||
|
||||
try
|
||||
{
|
||||
$test = \IPS\cms\Media\Folder::load( $testDir, 'media_folder_path' );
|
||||
$folderId = $test->id;
|
||||
}
|
||||
catch( \OutOfRangeException $ex )
|
||||
{
|
||||
$folder = new \IPS\cms\Media\Folder;
|
||||
$folder->parent = $folderId;
|
||||
$folder->name = $dir;
|
||||
$folder->path = $testDir;
|
||||
$folder->save();
|
||||
$folderId = $folder->id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$media = new \IPS\cms\Media;
|
||||
$media->parent = $folderId;
|
||||
$media->filename = $filename;
|
||||
$media->added = time();
|
||||
$media->full_path = $path;
|
||||
$media->filename_stored = $folderId . '_' . $filename;
|
||||
$media->file_object = \IPS\File::create( 'cms_Media', $media->filename_stored, $contents, 'pages_media', TRUE, NULL, FALSE );
|
||||
$media->is_image = $media->file_object->isImage();
|
||||
$media->save();
|
||||
|
||||
return $media->id;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,434 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Menu Model
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @since 15 Sept 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\cms\Pages;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Menu Model
|
||||
*/
|
||||
class _Menu extends \IPS\Node\Model
|
||||
{
|
||||
/**
|
||||
* @brief [ActiveRecord] Multiton Store
|
||||
*/
|
||||
protected static $multitons;
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Table
|
||||
*/
|
||||
public static $databaseTable = 'cms_page_menu';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Prefix
|
||||
*/
|
||||
public static $databasePrefix = 'menu_';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] ID Database Column
|
||||
*/
|
||||
public static $databaseColumnId = 'id';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database ID Fields
|
||||
*/
|
||||
protected static $databaseIdFields = array();
|
||||
|
||||
/**
|
||||
* @brief [Node] Parent ID Database Column
|
||||
*/
|
||||
public static $databaseColumnParent = 'parent_id';
|
||||
|
||||
/**
|
||||
* @brief [Node] Parent ID Root Value
|
||||
* @note This normally doesn't need changing though some legacy areas use -1 to indicate a root node
|
||||
*/
|
||||
public static $databaseColumnParentRootValue = 0;
|
||||
|
||||
/**
|
||||
* @brief [Node] Order Database Column
|
||||
*/
|
||||
public static $databaseColumnOrder = 'position';
|
||||
|
||||
/**
|
||||
* @brief [Node] Node Title
|
||||
*/
|
||||
public static $nodeTitle = 'cms_menu';
|
||||
|
||||
/**
|
||||
* @brief [Node] Show forms modally?
|
||||
*/
|
||||
public static $modalForms = TRUE;
|
||||
|
||||
/**
|
||||
* @brief [Node] Title prefix. If specified, will look for a language key with "{$key}_title" as the key
|
||||
*/
|
||||
public static $titleLangPrefix = 'cms_menu_title_';
|
||||
|
||||
/**
|
||||
* @brief [Node] ACP Restrictions
|
||||
* @code
|
||||
array(
|
||||
'app' => 'core', // The application key which holds the restrictrions
|
||||
'module' => 'foo', // The module key which holds the restrictions
|
||||
'map' => array( // [Optional] The key for each restriction - can alternatively use "prefix"
|
||||
'add' => 'foo_add',
|
||||
'edit' => 'foo_edit',
|
||||
'permissions' => 'foo_perms',
|
||||
'delete' => 'foo_delete'
|
||||
),
|
||||
'all' => 'foo_manage', // [Optional] The key to use for any restriction not provided in the map (only needed if not providing all 4)
|
||||
'prefix' => 'foo_', // [Optional] Rather than specifying each key in the map, you can specify a prefix, and it will automatically look for restrictions with the key "[prefix]_add/edit/permissions/delete"
|
||||
* @endcode
|
||||
*/
|
||||
protected static $restrictions = array(
|
||||
'app' => 'cms',
|
||||
'module' => 'pages',
|
||||
'all' => 'page_manage',
|
||||
'prefix' => 'page_'
|
||||
);
|
||||
|
||||
/**
|
||||
* Form elements
|
||||
*
|
||||
* @param \IPS\cms\Pages\Menu|null $node Menu item
|
||||
* @return array
|
||||
*/
|
||||
public static function formElements( $node=NULL, $forceType=NULL )
|
||||
{
|
||||
$form = array();
|
||||
|
||||
if ( $forceType === NULL )
|
||||
{
|
||||
$form['menu_type'] = new \IPS\Helpers\Form\Select( 'menu_type', ( $node !== NULL ? $node->type : 'page' ), TRUE, array(
|
||||
'options' => array(
|
||||
'page' => 'cms_menu_form_type_page',
|
||||
'url' => 'cms_menu_form_type_url',
|
||||
'folder' => 'cms_menu_form_type_folder',
|
||||
#'separator' => 'cms_menu_form_type_separator'
|
||||
),
|
||||
'toggles' => array(
|
||||
'page' => array( 'menu_content_page', 'menu_title_page', 'menu_permission_from_page'),
|
||||
'url' => array( 'menu_content_url', 'menu_title_url', 'menu_permission' ),
|
||||
'folder' => array( 'menu_title_folder', 'menu_permission')
|
||||
)
|
||||
) );
|
||||
}
|
||||
|
||||
/* Page fields */
|
||||
if ( $forceType !== 'page' )
|
||||
{
|
||||
$pages = array();
|
||||
foreach( \IPS\cms\Pages\Page::roots() as $id => $page )
|
||||
{
|
||||
$pages[ $id ] = $page->_title . ' (' . $page->full_path . ')';
|
||||
}
|
||||
|
||||
$form['menu_content_page'] = new \IPS\Helpers\Form\Select( 'menu_content_page', $node !== NULL ? ( $node->type === 'page' ? $node->content : NULL ) : 0, FALSE, array(
|
||||
'options' => $pages
|
||||
), NULL, NULL, NULL, 'menu_content_page' );
|
||||
}
|
||||
|
||||
$form['menu_title_page'] = new \IPS\Helpers\Form\Translatable( 'menu_title_page', NULL, FALSE, array( 'app' => 'cms', 'key' => ( ( ! empty( $node ) and $node->type === 'page' ) ? "cms_menu_title_" . $node->id : NULL ), 'maxLength' => 64 ), NULL, NULL, NULL, 'menu_title_page' );
|
||||
|
||||
/* URL Fields */
|
||||
if ( $forceType === NULL or $forceType === 'url' )
|
||||
{
|
||||
$form['menu_content_url'] = new \IPS\Helpers\Form\Text( 'menu_content_url', $node !== NULL ? ( $node->type === 'url' ? $node->content : NULL ) : '', FALSE, array(), NULL, NULL, NULL, 'menu_content_url' );
|
||||
|
||||
$form['menu_title_url'] = new \IPS\Helpers\Form\Translatable( 'menu_title_url', NULL, FALSE, array( 'app' => 'cms', 'key' => ( ( ! empty( $node ) and $node->type === 'url' ) ? "cms_menu_title_" . $node->id : NULL ), 'maxLength' => 64 ), NULL, NULL, NULL, 'menu_title_url' );
|
||||
}
|
||||
|
||||
/* Folder fields */
|
||||
if ( $forceType === NULL or $forceType === 'folder' )
|
||||
{
|
||||
$form['menu_title_folder'] = new \IPS\Helpers\Form\Translatable( 'menu_title_folder', NULL, FALSE, array( 'app' => 'cms', 'key' => ( ( ! empty( $node ) and $node->type === 'folder' ) ? "cms_menu_title_" . $node->id : NULL ), 'maxLength' => 64 ), NULL, NULL, NULL, 'menu_title_folder' );
|
||||
}
|
||||
|
||||
/* Shared fields */
|
||||
$form['menu_parent_id'] = new \IPS\Helpers\Form\Node( 'menu_parent_id', $node !== NULL ? intval( $node->parent_id ) : 0, FALSE, array(
|
||||
'class' => '\IPS\cms\Pages\Menu',
|
||||
'zeroVal' => 'node_no_parent',
|
||||
'permissionCheck' => function( $node )
|
||||
{
|
||||
return $node->type === 'folder';
|
||||
}
|
||||
), NULL, NULL, NULL, 'menu_parent_id' );
|
||||
|
||||
$form['menu_permission_from_page'] = new \IPS\Helpers\Form\Radio( 'menu_permission_type', $node !== NULL ? ( $node->permission === 'page' ? 'page' : 'manual' ) : ( $forceType === 'page' ? 'page' : 'manual' ), FALSE, array(
|
||||
'options' => array(
|
||||
'page' => 'cms_menu_form_perm_page',
|
||||
'manual' => 'cms_menu_form_perm_manual'
|
||||
),
|
||||
'toggles' => array(
|
||||
'manual' => array( 'menu_permission' )
|
||||
)
|
||||
), NULL, NULL, NULL, 'menu_permission_from_page' );
|
||||
|
||||
$form['menu_permission'] = new \IPS\Helpers\Form\Select( 'menu_permission', ( $node !== NULL ) ? ( ( $node->permission === '*' ) ? '*' : explode( ',', $node->permission ) ) : NULL, FALSE, array(
|
||||
'options' => array_combine( array_keys( \IPS\Member\Group::groups() ), array_map( function( $_group ) { return (string) $_group; }, \IPS\Member\Group::groups() ) ),
|
||||
'multiple' => true,
|
||||
'unlimited' => '*',
|
||||
'unlimitedLang' => 'cms_menu_perm_any'
|
||||
), NULL, NULL, NULL, 'menu_permission' );
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear caches
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function clearCaches()
|
||||
{
|
||||
unset( \IPS\Data\Store::i()->cms_menu );
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Set Title
|
||||
*
|
||||
* @param string $title Title
|
||||
* @return string|null
|
||||
*/
|
||||
protected function set__title( $title )
|
||||
{
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Get Title
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
protected function get__title()
|
||||
{
|
||||
if ( ! $this->title AND $this->type === 'page' )
|
||||
{
|
||||
try
|
||||
{
|
||||
$this->title = \IPS\cms\Pages\Page::load( $this->content )->_title;
|
||||
}
|
||||
catch( \OutOfRangeException $ex )
|
||||
{
|
||||
$this->title = '';
|
||||
}
|
||||
}
|
||||
else if ( ! $this->title )
|
||||
{
|
||||
/* This is stored in a separate \Data\Store cache, so we can't return the hash */
|
||||
$this->title = \IPS\Member::loggedIn()->language()->get( 'cms_menu_title_' . $this->id );
|
||||
}
|
||||
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Get URL
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
protected function get__url()
|
||||
{
|
||||
if ( $this->type === 'page' )
|
||||
{
|
||||
try
|
||||
{
|
||||
return \IPS\cms\Pages\Page::load( $this->content )->url();
|
||||
}
|
||||
catch( \OutOfRangeException $ex )
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Return the custom badge for each row
|
||||
*
|
||||
* @return NULL|array Null for no badge, or an array of badge data (0 => CSS class type, 1 => language string, 2 => optional raw HTML to show instead of language string)
|
||||
*/
|
||||
protected function get__badge()
|
||||
{
|
||||
if ( ! $this->permission )
|
||||
{
|
||||
return array( 'ipsBadge ipsBadge_negative', 'cms_menu_no_item_perm' );
|
||||
}
|
||||
|
||||
return ( $this->type === 'folder' ) ? NULL : array( 'ipsBadge ipsBadge_intermediary ipsPos_right', 'cms_menu_form_type_' . $this->type );
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Get buttons to display in tree
|
||||
* Example code explains return value
|
||||
*
|
||||
* @code
|
||||
array(
|
||||
array(
|
||||
'icon' => 'plus-circle', // Name of FontAwesome icon to use
|
||||
'title' => 'foo', // Language key to use for button's title parameter
|
||||
'link' => \IPS\Http\Url::internal( 'app=foo...' ) // URI to link to
|
||||
'class' => 'modalLink' // CSS Class to use on link (Optional)
|
||||
),
|
||||
... // Additional buttons
|
||||
);
|
||||
* @endcode
|
||||
* @param string $url Base URL
|
||||
* @param bool $subnode Is this a subnode?
|
||||
* @return array
|
||||
*/
|
||||
public function getButtons( $url, $subnode=FALSE )
|
||||
{
|
||||
$buttons = parent::getButtons( $url, $subnode );
|
||||
|
||||
if ( isset( $buttons['copy'] ) and $this->type === 'folder' )
|
||||
{
|
||||
unset( $buttons['copy'] );
|
||||
}
|
||||
|
||||
return $buttons;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sortable name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSortableName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Add/Edit Form
|
||||
*
|
||||
* @param \IPS\Helpers\Form $form The form
|
||||
* @return void
|
||||
*/
|
||||
public function form( &$form )
|
||||
{
|
||||
/* Build form */
|
||||
foreach( static::formElements( $this ) as $element )
|
||||
{
|
||||
$form->add( $element );
|
||||
}
|
||||
|
||||
if ( $this->id )
|
||||
{
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('cms_menu_edit', FALSE, array( 'sprintf' => array( $this->_title ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('cms_menu_adding');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Format form values from add/edit form for save
|
||||
*
|
||||
* @param array $values Values from the form
|
||||
* @return array
|
||||
*/
|
||||
public function formatFormValues( $values )
|
||||
{
|
||||
if ( ! $this->id )
|
||||
{
|
||||
$this->parent_id = 0;
|
||||
$this->save();
|
||||
}
|
||||
|
||||
if( isset( $values['menu_type'] ) )
|
||||
{
|
||||
$title = '';
|
||||
$content = NULL;
|
||||
|
||||
switch ( $values['menu_type'] )
|
||||
{
|
||||
case 'page':
|
||||
$title = $values['menu_title_page'];
|
||||
$content = $values['menu_content_page'];
|
||||
break;
|
||||
case 'url':
|
||||
$title = $values['menu_title_url'];
|
||||
$content = $values['menu_content_url'];
|
||||
break;
|
||||
case 'folder':
|
||||
$title = $values['menu_title_folder'];
|
||||
break;
|
||||
}
|
||||
|
||||
/* We need to store something in menu_title field in the database as we can leave this blank to get the current page title. We can't examine an addToStack to see if any data was returned */
|
||||
$values['title'] = current( $title );
|
||||
$values['content'] = $content;
|
||||
|
||||
\IPS\Lang::saveCustom( 'cms', "cms_menu_title_" . $this->id, $title );
|
||||
|
||||
unset( $values['menu_title_folder'], $values['menu_title_url'], $values['menu_title_page'], $values['menu_content_page'], $values['menu_content_url'] );
|
||||
}
|
||||
|
||||
if( isset( $values['menu_permission'] ) )
|
||||
{
|
||||
$values['menu_permission'] = ( is_array( $values['menu_permission'] ) ) ? implode( ',', $values['menu_permission'] ) : $values['menu_permission'];
|
||||
}
|
||||
|
||||
if ( isset( $values['menu_type'] ) AND $values['menu_type'] === 'page' and $values['menu_permission_type'] === 'page' )
|
||||
{
|
||||
$values['menu_permission'] = 'page';
|
||||
}
|
||||
|
||||
if ( isset( $values['menu_parent_id'] ) AND ( ! empty( $values['menu_parent_id'] ) OR $values['menu_parent_id'] === 0 ) )
|
||||
{
|
||||
$values['menu_parent_id'] = ( $values['menu_parent_id'] === 0 ) ? 0 : $values['menu_parent_id']->id;
|
||||
}
|
||||
|
||||
if( isset( $values['menu_permission_type'] ) )
|
||||
{
|
||||
unset( $values['menu_permission_type'] );
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Does the currently logged in user have permission to add a child node to this node?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canAdd()
|
||||
{
|
||||
if ( parent::canAdd() )
|
||||
{
|
||||
return $this->type === 'folder';
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Save
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
static::clearCaches();
|
||||
parent::save();
|
||||
}
|
||||
}
|
||||
@@ -51,7 +51,7 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
/**
|
||||
* @brief [Node] Parent ID Database Column
|
||||
*/
|
||||
public static $databaseColumnParent = null;
|
||||
public static $databaseColumnParent = 'folder_id';
|
||||
|
||||
/**
|
||||
* @brief [Node] Parent Node ID Database Column
|
||||
@@ -367,7 +367,6 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
{
|
||||
$url->data['query'] = $queryString;
|
||||
}
|
||||
|
||||
return \IPS\Http\Url::createFromArray( $url->data );
|
||||
}
|
||||
|
||||
@@ -384,7 +383,7 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
/* Do we have a page with this path? */
|
||||
try
|
||||
{
|
||||
return static::load( $newPath, 'page_full_path' )->url();
|
||||
return static::load( $newPath, 'page_full_path' );
|
||||
}
|
||||
catch( \OutOfRangeException $ex )
|
||||
{
|
||||
@@ -499,6 +498,33 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a custom error page
|
||||
*
|
||||
* @param string $title Title of the page
|
||||
* @param string $message language key for error message
|
||||
* @param mixed $code Error code
|
||||
* @param int $httpStatusCode HTTP Status Code
|
||||
* @param array $httpHeaders Additional HTTP Headers
|
||||
* @return void
|
||||
*/
|
||||
static public function errorPage( $title, $message, $code, $httpStatusCode, $httpHeaders )
|
||||
{
|
||||
try
|
||||
{
|
||||
$page = static::load( \IPS\Settings::i()->cms_error_page );
|
||||
$page->content = str_replace( '{error_message}', $message, $page->content );
|
||||
$page->content = str_replace( '{error_code}', $code, $page->content );
|
||||
|
||||
$page->output( $title, $httpStatusCode, $httpHeaders );
|
||||
}
|
||||
catch( \Exception $ex )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['enabled'] = FALSE;
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->globalTemplate( $title, \IPS\Theme::i()->getTemplate( 'global', 'core' )->error( $title, $message, $code, NULL ), array( 'app' => \IPS\Dispatcher::i()->application ? \IPS\Dispatcher::i()->application->directory : NULL, 'module' => \IPS\Dispatcher::i()->module ? \IPS\Dispatcher::i()->module->key : NULL, 'controller' => \IPS\Dispatcher::i()->controller ) ), $httpStatusCode, 'text/html', $httpHeaders, FALSE, FALSE );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Form elements
|
||||
*
|
||||
@@ -562,54 +588,50 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
'subnodes' => false
|
||||
), NULL, NULL, NULL, 'page_folder_id' );
|
||||
|
||||
if ( $pageType === 'html' )
|
||||
|
||||
$return['page_ipb_wrapper'] = new \IPS\Helpers\Form\YesNo( 'page_ipb_wrapper', $item AND $item->id ? $item->ipb_wrapper : 1, TRUE, array(
|
||||
'togglesOn' => array( 'page_show_sidebar' ),
|
||||
'togglesOff' => array( 'page_wrapper_template' )
|
||||
), NULL, NULL, NULL, 'page_ipb_wrapper' );
|
||||
|
||||
$return['page_show_sidebar'] = new \IPS\Helpers\Form\YesNo( 'page_show_sidebar', $item ? $item->show_sidebar : TRUE, FALSE, array(), NULL, NULL, NULL, 'page_show_sidebar' );
|
||||
|
||||
$wrapperTemplates = array( '_none_' => \IPS\Member::loggedIn()->language()->addToStack('cms_page_wrapper_template_none') );
|
||||
foreach( \IPS\cms\Templates::getTemplates( \IPS\cms\Templates::RETURN_PAGE + \IPS\cms\Templates::RETURN_DATABASE_AND_IN_DEV ) as $id => $obj )
|
||||
{
|
||||
$return['page_ipb_wrapper'] = new \IPS\Helpers\Form\YesNo( 'page_ipb_wrapper', $item AND $item->id ? $item->ipb_wrapper : 1, TRUE, array(
|
||||
'togglesOn' => array( 'page_show_sidebar' ),
|
||||
'togglesOff' => array( 'page_wrapper_template' )
|
||||
), NULL, NULL, NULL, 'page_ipb_wrapper' );
|
||||
|
||||
$return['page_show_sidebar'] = new \IPS\Helpers\Form\YesNo( 'page_show_sidebar', $item ? $item->show_sidebar : TRUE, FALSE, array(), NULL, NULL, NULL, 'page_show_sidebar' );
|
||||
|
||||
$wrapperTemplates = array( '_none_' => \IPS\Member::loggedIn()->language()->addToStack('cms_page_wrapper_template_none') );
|
||||
foreach( \IPS\cms\Templates::getTemplates( \IPS\cms\Templates::RETURN_PAGE + \IPS\cms\Templates::RETURN_DATABASE_AND_IN_DEV ) as $id => $obj )
|
||||
if ( $obj->isSuitableForCustomWrapper() )
|
||||
{
|
||||
if ( $obj->isSuitableForCustomWrapper() )
|
||||
{
|
||||
$wrapperTemplates[ \IPS\cms\Templates::readableGroupName( $obj->group ) ][ $obj->group . '__' . $obj->title . '__' . $obj->key ] = \IPS\cms\Templates::readableGroupName( $obj->title );
|
||||
}
|
||||
$wrapperTemplates[ \IPS\cms\Templates::readableGroupName( $obj->group ) ][ $obj->group . '__' . $obj->title . '__' . $obj->key ] = \IPS\cms\Templates::readableGroupName( $obj->title );
|
||||
}
|
||||
|
||||
/* List of templates */
|
||||
$return['page_wrapper_template'] = new \IPS\Helpers\Form\Select( 'page_wrapper_template', ( $item ? $item->wrapper_template : NULL ), FALSE, array(
|
||||
'options' => $wrapperTemplates
|
||||
), NULL, NULL, \IPS\Theme::i()->getTemplate( 'pages', 'cms', 'admin' )->previewTemplateLink(), 'page_wrapper_template' );
|
||||
}
|
||||
else
|
||||
|
||||
/* List of templates */
|
||||
$return['page_wrapper_template'] = new \IPS\Helpers\Form\Select( 'page_wrapper_template', ( $item ? $item->wrapper_template : NULL ), FALSE, array(
|
||||
'options' => $wrapperTemplates
|
||||
), NULL, NULL, \IPS\Theme::i()->getTemplate( 'pages', 'cms', 'admin' )->previewTemplateLink(), 'page_wrapper_template' );
|
||||
|
||||
if ( count( \IPS\Theme::themes() ) > 1 )
|
||||
{
|
||||
if ( count( \IPS\Theme::themes() ) > 1 )
|
||||
$themes = array( 0 => 'cms_page_theme_id_default' );
|
||||
foreach ( \IPS\Theme::themes() as $theme )
|
||||
{
|
||||
$themes = array( 0 => 'cms_page_theme_id_default' );
|
||||
foreach ( \IPS\Theme::themes() as $theme )
|
||||
{
|
||||
$themes[ $theme->id ] = $theme->_title;
|
||||
}
|
||||
|
||||
$return['page_theme'] = new \IPS\Helpers\Form\Select( 'page_theme', $item ? $item->theme : 0, FALSE, array( 'options' => $themes ), NULL, NULL, NULL, 'page_theme' );
|
||||
$themes[ $theme->id ] = $theme->_title;
|
||||
}
|
||||
|
||||
$builderTemplates = array();
|
||||
foreach( \IPS\cms\Templates::getTemplates( \IPS\cms\Templates::RETURN_PAGE + \IPS\cms\Templates::RETURN_DATABASE_AND_IN_DEV ) as $id => $obj )
|
||||
{
|
||||
if ( $obj->isSuitableForBuilderWrapper() )
|
||||
{
|
||||
$builderTemplates[ \IPS\cms\Templates::readableGroupName( $obj->group ) ][ $obj->group . '__' . $obj->title . '__' . $obj->key ] = \IPS\cms\Templates::readableGroupName( $obj->title );
|
||||
}
|
||||
}
|
||||
|
||||
$return['page_template'] = new \IPS\Helpers\Form\Select( 'page_template', $item->template ? $item->template : FALSE, FALSE, array( 'options' => $builderTemplates ), NULL, NULL, NULL, 'page_template' );
|
||||
$return['page_theme'] = new \IPS\Helpers\Form\Select( 'page_theme', $item ? $item->theme : 0, FALSE, array( 'options' => $themes ), NULL, NULL, NULL, 'page_theme' );
|
||||
}
|
||||
|
||||
$builderTemplates = array();
|
||||
foreach( \IPS\cms\Templates::getTemplates( \IPS\cms\Templates::RETURN_PAGE + \IPS\cms\Templates::RETURN_DATABASE_AND_IN_DEV ) as $id => $obj )
|
||||
{
|
||||
if ( $obj->isSuitableForBuilderWrapper() )
|
||||
{
|
||||
$builderTemplates[ \IPS\cms\Templates::readableGroupName( $obj->group ) ][ $obj->group . '__' . $obj->title . '__' . $obj->key ] = \IPS\cms\Templates::readableGroupName( $obj->title );
|
||||
}
|
||||
}
|
||||
|
||||
$return['page_template'] = new \IPS\Helpers\Form\Select( 'page_template', ( $item and $item->template ) ? $item->template : FALSE, FALSE, array( 'options' => $builderTemplates ), NULL, NULL, NULL, 'page_template' );
|
||||
|
||||
/* Page CSS and JS */
|
||||
$js = \IPS\cms\Templates::getTemplates( \IPS\cms\Templates::RETURN_ONLY_JS + \IPS\cms\Templates::RETURN_DATABASE_ONLY );
|
||||
$css = \IPS\cms\Templates::getTemplates( \IPS\cms\Templates::RETURN_ONLY_CSS + \IPS\cms\Templates::RETURN_DATABASE_ONLY );
|
||||
@@ -647,21 +669,32 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
$return['tab_content'] = array( 'content_page_form_tab__content', NULL, NULL, 'ipsForm_vertical' );
|
||||
|
||||
$tags = array();
|
||||
|
||||
|
||||
if ( $item and $item->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['{database="' . $db->_id . '" title="' . $db->_title . '"}'] = $db->_title;
|
||||
$tags['cms_tag_databases']['{database="' . $db->key . '"}'] = $db->_title;
|
||||
}
|
||||
}
|
||||
|
||||
foreach( \IPS\cms\Blocks\Block::roots( NULL, NULL ) as $id => $block )
|
||||
{
|
||||
$tags['{block="' . $block->_id . '" title="' . $block->_title . '"}'] = $block->_title;
|
||||
$tags['cms_tag_blocks']['{block="' . $block->key . '"}'] = $block->_title;
|
||||
}
|
||||
|
||||
$return['page_content'] = new \IPS\Helpers\Form\Codemirror( 'page_content', $item ? $item->content : NULL, FALSE, array( 'tags' => $tags ), function( $val )
|
||||
|
||||
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( static::$titleLangPrefix . $page['page_id'] );
|
||||
}
|
||||
|
||||
$return['page_content'] = new \IPS\Helpers\Form\Codemirror( 'page_content', $item ? htmlentities( $item->content, \IPS\HTMLENTITIES, 'UTF-8', TRUE ) : NULL, FALSE, array( 'tags' => $tags, 'height' => 600 ), function( $val )
|
||||
{
|
||||
/* Test */
|
||||
try
|
||||
@@ -702,12 +735,7 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
$page->saveForm( $page->formatFormValues( $values ), $pageType );
|
||||
|
||||
/* Set permissions */
|
||||
\IPS\Db::i()->insert( 'core_permission_index', array(
|
||||
'app' => 'cms',
|
||||
'perm_type' => 'pages',
|
||||
'perm_type_id' => $page->id,
|
||||
'perm_view' => '*'
|
||||
) );
|
||||
\IPS\Db::i()->update( 'core_permission_index', array( 'perm_view' => '*' ), array( 'app=? and perm_type=? and perm_type_id=?', 'cms', 'pages', $page->id ) );
|
||||
|
||||
return $page;
|
||||
}
|
||||
@@ -778,7 +806,40 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
\IPS\Db::i()->update( 'cms_pages', array( 'page_js_css_objects' => NULL ) );
|
||||
\IPS\cms\Templates::deleteCompiledFiles();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a datastore object of page IDs and URLs.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function buildPageUrlStore()
|
||||
{
|
||||
$store = array();
|
||||
foreach( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'cms_pages' ), 'IPS\cms\Pages\Page' ) as $page )
|
||||
{
|
||||
$perms = $page->permissions();
|
||||
$store[ $page->id ] = array( 'url' => (string) $page->url(), 'perm' => $perms['perm_view'] );
|
||||
}
|
||||
|
||||
\IPS\Data\Store::i()->pages_page_urls = $store;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns (and builds if required) the pages id => url datastore
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getPageUrlStore()
|
||||
{
|
||||
if ( ! isset( \IPS\Data\Store::i()->pages_page_urls ) )
|
||||
{
|
||||
static::buildPageUrlStore();
|
||||
}
|
||||
|
||||
return \IPS\Data\Store::i()->pages_page_urls;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set JS/CSS include keys
|
||||
*
|
||||
@@ -991,7 +1052,7 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
$return = array();
|
||||
$dbWidgets = array();
|
||||
$areas = array();
|
||||
|
||||
|
||||
foreach( \IPS\Db::i()->select( '*', 'cms_page_widget_areas', array( 'area_page_id=?', $this->id ) ) as $k => $widgetMain )
|
||||
{
|
||||
$widgets[ $widgetMain['area_area'] ] = json_decode( $widgetMain['area_widgets'], TRUE );
|
||||
@@ -1000,7 +1061,8 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
/* We need to execute database widgets first as this sets up the Database dispatcher correctly */
|
||||
foreach( $widgets[ $widgetMain['area_area'] ] as $widget )
|
||||
{
|
||||
if ( $widget['key'] === 'Database' )
|
||||
/* Do not attempt to re-parse database widgets if we already have */
|
||||
if ( ! \IPS\cms\Databases\Dispatcher::i()->databaseId AND $widget['key'] === 'Database' )
|
||||
{
|
||||
$orientation = ( ( $widgetMain['area_area'] == 'sidebar' ) ? 'vertical' : ( ( $widgetMain['area_area'] === 'header' OR $widgetMain['area_area'] === 'footer' ) ? 'horizontal' : $widgetMain['area_orientation'] ) );
|
||||
$dbWidgets[ $widget['unique'] ] = \IPS\Widget::load( \IPS\Application::load( $widget['app'] ), $widget['key'], $widget['unique'], ( isset( $widget['configuration'] ) ) ? $widget['configuration'] : array(), ( isset( $widget['restrict'] ) ? $widget['restrict'] : null ), $orientation );
|
||||
@@ -1017,7 +1079,7 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
{
|
||||
try
|
||||
{
|
||||
if ( $widget['key'] == 'Database' )
|
||||
if ( $widget['key'] == 'Database' and array_key_exists( $widget['unique'], $dbWidgets ) )
|
||||
{
|
||||
$_widget = $dbWidgets[ $widget['unique'] ];
|
||||
}
|
||||
@@ -1156,9 +1218,19 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
{
|
||||
$pageType = $this->type;
|
||||
}
|
||||
|
||||
|
||||
foreach( static::formElements( $this ) as $name => $field )
|
||||
{
|
||||
if ( $pageType !== 'html' and in_array( $name, array( 'page_ipb_wrapper', 'page_show_sidebar', 'page_wrapper_template' ) ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( $pageType === 'html' and in_array( $name, array( 'page_template' ) ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( is_array( $field ) )
|
||||
{
|
||||
if ( mb_substr( $name, 0, 4 ) === 'tab_' )
|
||||
@@ -1179,20 +1251,42 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
if ( ! $this->id )
|
||||
{
|
||||
$form->addTab( 'content_page_form_tab__menu' );
|
||||
$toggles = array();
|
||||
$toggles = array( 'menu_manager_access_type', 'menu_parent' );
|
||||
$formFields = array();
|
||||
|
||||
foreach( \IPS\cms\Pages\Menu::formElements( NULL, 'page' ) as $name => $field )
|
||||
|
||||
foreach( \IPS\cms\extensions\core\FrontNavigation\Pages::configuration( array() ) as $field )
|
||||
{
|
||||
$toggles[] = $name;
|
||||
$formFields[ $name ] = $field;
|
||||
if ( $field->name !== 'menu_content_page' )
|
||||
{
|
||||
$toggles[] = $field->name;
|
||||
$formFields[ $field->name ] = $field;
|
||||
}
|
||||
}
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'page_add_to_menu', FALSE, FALSE, array( 'togglesOn' => $toggles ) ) );
|
||||
|
||||
$roots = array();
|
||||
foreach ( \IPS\core\FrontNavigation::i()->roots( FALSE ) as $item )
|
||||
{
|
||||
$roots[ $item->id ] = $item->title();
|
||||
}
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'menu_parent', '*', NULL, array( 'options' => $roots ), NULL, NULL, NULL, 'menu_parent' ) );
|
||||
|
||||
|
||||
foreach( $formFields as $name => $field )
|
||||
{
|
||||
$form->add( $field );
|
||||
}
|
||||
|
||||
$groups = array();
|
||||
foreach ( \IPS\Member\Group::groups() as $group )
|
||||
{
|
||||
$groups[ $group->g_id ] = $group->name;
|
||||
}
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'menu_manager_access_type', 0, TRUE, array(
|
||||
'options' => array( 0 => 'menu_manager_access_type_inherit', 1 => 'menu_manager_access_type_override' ),
|
||||
'toggles' => array( 1 => array( 'menu_manager_access' ) )
|
||||
), NULL, NULL, NULL, 'menu_manager_access_type' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'menu_manager_access', '*', NULL, array( 'multiple' => TRUE, 'options' => $groups, 'unlimited' => '*', 'unlimitedLang' => 'everyone' ), NULL, NULL, NULL, 'menu_manager_access' ) );
|
||||
}
|
||||
|
||||
if ( $pageType === 'builder' )
|
||||
@@ -1296,20 +1390,39 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
{
|
||||
if( $values['page_add_to_menu'] )
|
||||
{
|
||||
$menuValues = array(
|
||||
'menu_type' => 'page',
|
||||
'menu_title_page' => $values['menu_title_page'],
|
||||
'menu_content_page' => $this->id,
|
||||
'menu_permission' => $values['menu_permission'],
|
||||
'menu_permission_type' => $values['menu_permission_type'],
|
||||
'menu_parent_id' => $values['menu_parent_id']
|
||||
$values = \IPS\cms\extensions\core\FrontNavigation\Pages::parseConfiguration( $values, $this->id );
|
||||
$config = array( 'menu_content_page' => $this->id );
|
||||
|
||||
foreach( array( 'menu_title_page_type', 'menu_title_page' ) as $field )
|
||||
{
|
||||
if ( isset( $values[ $field ] ) )
|
||||
{
|
||||
$config[ $field ] = $values[ $field ];
|
||||
}
|
||||
}
|
||||
|
||||
$save = array(
|
||||
'app' => 'cms',
|
||||
'extension' => 'Pages',
|
||||
'config' => json_encode( $config ),
|
||||
'parent' => $values['menu_parent'],
|
||||
'permissions' => $values['menu_manager_access'] == '*' ? '*' : implode( ',', $values['menu_manager_access'] )
|
||||
);
|
||||
|
||||
$menu = new \IPS\cms\Pages\Menu();
|
||||
$menu->saveForm( $menu->formatFormValues( $menuValues ) );
|
||||
|
||||
try
|
||||
{
|
||||
$save['position'] = \IPS\Db::i()->select( 'MAX(position)', 'core_menu', array( 'parent=?', \IPS\Request::i()->parent ) )->first() + 1;
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
{
|
||||
$save['position'] = 1;
|
||||
}
|
||||
|
||||
\IPS\Db::i()->insert( 'core_menu', $save );
|
||||
unset( \IPS\Data\Store::i()->frontNavigation );
|
||||
}
|
||||
|
||||
unset( $values['page_add_to_menu'], $values['menu_title_page'], $values['menu_permission'], $values['menu_permission_type'], $values['menu_parent_id'] );
|
||||
unset( $values['page_add_to_menu'], $values['menu_title_page_type'], $values['menu_title_page'], $values['menu_parent'], $values['menu_manager_access'], $values['menu_manager_access_type'] );
|
||||
}
|
||||
|
||||
return $values;
|
||||
@@ -1683,13 +1796,42 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
\IPS\Db::i()->delete( 'cms_page_menu', array( 'menu_type=? AND menu_content=?', 'page', $this->id ) );
|
||||
unset( \IPS\Data\Store::i()->cms_menu );
|
||||
|
||||
$delete = $this->getMenuItemIds();
|
||||
|
||||
if ( count( $delete ) )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_menu', \IPS\Db::i()->in( 'id', $delete ) );
|
||||
}
|
||||
|
||||
unset( \IPS\Data\Store::i()->frontNavigation );
|
||||
|
||||
return parent::delete();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns core_menu ids for all menu items associated with this page
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMenuItemIds()
|
||||
{
|
||||
$items = array();
|
||||
foreach( \IPS\Db::i()->select( '*', 'core_menu', array( 'app=? AND extension=?', 'cms', 'Pages' ) ) as $item )
|
||||
{
|
||||
$json = json_decode( $item['config'], TRUE );
|
||||
|
||||
if ( isset( $json['menu_content_page'] ) )
|
||||
{
|
||||
if ( $json['menu_content_page'] == $this->id )
|
||||
{
|
||||
$items[] = $item['id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the permission index permissions
|
||||
@@ -1700,9 +1842,9 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
*/
|
||||
public function setPermissions( $insert, \IPS\Helpers\Form\Matrix $matrix )
|
||||
{
|
||||
\IPS\cms\Pages\Menu::clearCaches();
|
||||
parent::setPermissions( $insert, $matrix );
|
||||
|
||||
static::buildPageUrlStore();
|
||||
|
||||
/* Update perms if we have a child database */
|
||||
try
|
||||
{
|
||||
@@ -1732,10 +1874,10 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
{
|
||||
static::deleteCompiled( $this->id );
|
||||
}
|
||||
|
||||
\IPS\cms\Pages\Menu::clearCaches();
|
||||
|
||||
parent::save();
|
||||
|
||||
static::buildPageUrlStore();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1758,7 +1900,7 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
\IPS\DB::i()->update( 'cms_pages', array( 'page_default' => 0 ), array( 'page_folder_id=?', $this->folder_id ) );
|
||||
\IPS\DB::i()->update( 'cms_pages', array( 'page_default' => 1 ), array( 'page_id=?', $this->id ) );
|
||||
|
||||
\IPS\cms\Pages\Menu::clearCaches();
|
||||
static::buildPageUrlStore();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1772,4 +1914,140 @@ class _Page extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
$this->full_path = trim( $path . '/' . $this->seo_name, '/' );
|
||||
$this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a page
|
||||
*
|
||||
* @param int $httpStatusCode HTTP Status Code
|
||||
* @param array $httpHeaders Additional HTTP Headers
|
||||
* @throws \ErrorException
|
||||
* @return void
|
||||
*/
|
||||
public function output( $title=NULL, $httpStatusCode=NULL, $httpHeaders=NULL )
|
||||
{
|
||||
$includes = $this->getIncludes();
|
||||
|
||||
if ( isset( $includes['js'] ) and is_array( $includes['js'] ) )
|
||||
{
|
||||
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, array_values( $includes['js'] ) );
|
||||
}
|
||||
|
||||
/* Display */
|
||||
if ( $this->ipb_wrapper or $this->type === 'builder' )
|
||||
{
|
||||
$this->setTheme();
|
||||
$nav = array();
|
||||
|
||||
\IPS\Output::i()->title = $this->getHtmlTitle();
|
||||
|
||||
/* This has to be done after setTheme(), otherwise \IPS\Theme::switchTheme() can wipe out CSS includes */
|
||||
if ( isset( $includes['css'] ) and is_array( $includes['css'] ) )
|
||||
{
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, array_values( $includes['css'] ) );
|
||||
}
|
||||
|
||||
if ( $this->type === 'builder' )
|
||||
{
|
||||
list( $group, $name, $key ) = explode( '__', $this->template );
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('pages')->globalWrap( $nav, \IPS\cms\Theme::i()->getTemplate($group, 'cms', 'page')->$name( $this, $this->getWidgets() ), $this );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Populate \IPS\Output::i()->sidebar['widgets'] sidebar/header/footer widgets */
|
||||
$this->getWidgets();
|
||||
|
||||
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('pages')->globalWrap( $nav, $this->getHtmlContent(), $this );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->sidebar['enabled'] = true;
|
||||
|
||||
/* Set the meta tags, but do not reset them if they are already set - articles can define custom meta tags and this code
|
||||
overwrites the ones set by articles if we don't verify they aren't set first */
|
||||
if ( $this->meta_keywords AND ( !isset( \IPS\Output::i()->metaTags['keywords'] ) OR !\IPS\Output::i()->metaTags['keywords'] ) )
|
||||
{
|
||||
\IPS\Output::i()->metaTags['keywords'] = $this->meta_keywords;
|
||||
}
|
||||
|
||||
if ( $this->meta_description AND ( !isset( \IPS\Output::i()->metaTags['description'] ) OR !\IPS\Output::i()->metaTags['description'] ) )
|
||||
{
|
||||
\IPS\Output::i()->metaTags['description'] = $this->meta_description;
|
||||
}
|
||||
|
||||
/* Can only disable sidebar if HTML page */
|
||||
if ( ! $this->show_sidebar and $this->type === 'html' )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['enabled'] = false;
|
||||
}
|
||||
|
||||
if ( isset( \IPS\Settings::i()->cms_error_page ) and \IPS\Settings::i()->cms_error_page and \IPS\Settings::i()->cms_error_page == $this->id )
|
||||
{
|
||||
\IPS\Output::i()->sidebar['enabled'] = false;
|
||||
}
|
||||
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'pages/page.css', 'cms', 'front' ) );
|
||||
|
||||
if ( ! ( \IPS\Application::load('cms')->default AND ! $this->folder_id AND $this->default ) )
|
||||
{
|
||||
\IPS\Output::i()->breadcrumb['module'] = array( $this->url(), $this->_title );
|
||||
}
|
||||
|
||||
if ( isset( \IPS\Settings::i()->cms_error_page ) and \IPS\Settings::i()->cms_error_page and \IPS\Settings::i()->cms_error_page == $this->id )
|
||||
{
|
||||
/* Set the title */
|
||||
\IPS\Output::i()->title = ( $title ) ? $title : $this->getHtmlTitle();
|
||||
\IPS\Output::i()->output = $this->getHtmlContent();
|
||||
\IPS\Member::loggedIn()->language()->parseOutputForDisplay( \IPS\Output::i()->title );
|
||||
|
||||
/* Send straight to the output engine */
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->globalTemplate( \IPS\Output::i()->title, \IPS\Output::i()->output, array( 'app' => \IPS\Dispatcher::i()->application->directory, 'module' => \IPS\Dispatcher::i()->module->key, 'controller' => \IPS\Dispatcher::i()->controller ) ), ( $httpStatusCode ? $httpStatusCode : 200 ), 'text/html', ( $httpHeaders ? $httpHeaders : \IPS\Output::i()->httpHeaders ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->allowDefaultWidgets = FALSE;
|
||||
|
||||
/* Let the dispatcher finish off and show page */
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( isset( $includes['css'] ) and is_array( $includes['css'] ) )
|
||||
{
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, array_values( $includes['css'] ) );
|
||||
}
|
||||
|
||||
if ( $this->meta_keywords AND ( !isset( \IPS\Output::i()->metaTags['keywords'] ) OR !\IPS\Output::i()->metaTags['keywords'] ) )
|
||||
{
|
||||
\IPS\Output::i()->metaTags['keywords'] = $this->meta_keywords;
|
||||
}
|
||||
|
||||
if ( $this->meta_description AND ( !isset( \IPS\Output::i()->metaTags['description'] ) OR !\IPS\Output::i()->metaTags['description'] ) )
|
||||
{
|
||||
\IPS\Output::i()->metaTags['description'] = $this->meta_description;
|
||||
}
|
||||
|
||||
/* Meta tags */
|
||||
\IPS\Output::i()->buildMetaTags();
|
||||
|
||||
if ( $this->wrapper_template and $this->wrapper_template !== '_none_' and ! \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
try
|
||||
{
|
||||
list( $group, $name, $key ) = explode( '__', $this->wrapper_template );
|
||||
\IPS\Output::i()->sendOutput( \IPS\cms\Theme::i()->getTemplate($group, 'cms', 'page')->$name( $this->getHtmlContent(), $this->getHtmlTitle() ), 200, $this->getContentType(), \IPS\Output::i()->httpHeaders );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the title */
|
||||
\IPS\Output::i()->title = ( $title ) ? $title : $this->getHtmlTitle();
|
||||
\IPS\Member::loggedIn()->language()->parseOutputForDisplay( \IPS\Output::i()->title );
|
||||
|
||||
/* Send straight to the output engine */
|
||||
\IPS\Output::i()->sendOutput( $this->getHtmlContent(), ( $httpStatusCode ? $httpStatusCode : 200 ), $this->getContentType(), ( $httpHeaders ? $httpHeaders : \IPS\Output::i()->httpHeaders ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -135,6 +135,7 @@ class _Comment extends \IPS\Content\Comment implements \IPS\Content\ReportCenter
|
||||
if ( isset( $item::$databaseColumnMap['num_comments'] ) )
|
||||
{
|
||||
$item->resyncCommentCounts();
|
||||
$item->save();
|
||||
}
|
||||
|
||||
if ( $item->containerWrapper() AND $item->container()->_comments !== NULL )
|
||||
|
||||
@@ -100,7 +100,18 @@ class _CommentTopicSync extends \IPS\cms\Records\Comment
|
||||
public function item()
|
||||
{
|
||||
$itemClass = static::$itemClass;
|
||||
return $itemClass::load( \IPS\Request::i()->id );
|
||||
$lookFor = 'IPS\cms\Records\RecordsTopicSync';
|
||||
|
||||
if ( mb_substr( $itemClass, 0, mb_strlen( $lookFor ) ) === $lookFor )
|
||||
{
|
||||
$id = $this->topic_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
$id = \IPS\Request::i()->id;
|
||||
}
|
||||
|
||||
return $itemClass::load( $id );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,19 +121,24 @@ class _CommentTopicSync extends \IPS\cms\Records\Comment
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
parent::delete();
|
||||
|
||||
try
|
||||
{
|
||||
$topic = \IPS\forums\Topic::load( $this->topic_id );
|
||||
$topic->resyncCommentCounts();
|
||||
$topic->resyncLastComment();
|
||||
}
|
||||
catch( \OutOfRangeException $ex )
|
||||
{
|
||||
}
|
||||
/* We need the classname to be \IPS\forums\Topic\Post so topic/forum sync occur and to ensure post is removed from search index */
|
||||
$comment = \IPS\forums\Topic\Post::load( $this->pid );
|
||||
$comment->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit Comment Contents - Note: does not add edit log
|
||||
*
|
||||
* @param string $newContent New content
|
||||
* @return string|NULL
|
||||
*/
|
||||
public function editContents( $newContent )
|
||||
{
|
||||
$comment = \IPS\forums\Topic\Post::load( $this->pid );
|
||||
$comment->editContents( $newContent );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Addition where needed for fetching comments
|
||||
*
|
||||
|
||||
@@ -124,7 +124,7 @@ class _Records extends \IPS\Content\Item implements
|
||||
/**
|
||||
* @brief Icon
|
||||
*/
|
||||
public static $icon = 'file-text-o';
|
||||
public static $icon = 'file-text';
|
||||
|
||||
/**
|
||||
* @brief Reputation Type
|
||||
@@ -177,8 +177,17 @@ class _Records extends \IPS\Content\Item implements
|
||||
*/
|
||||
public static function getCommentsPerPage()
|
||||
{
|
||||
/* Normally we check if we are using the forums at the record level, however this is a static method called so we can only try to do our best to guess */
|
||||
if( static::database()->forum_record and static::database()->forum_comments and \IPS\Application::appIsEnabled('forums') )
|
||||
if ( ! empty( \IPS\cms\Databases\Dispatcher::i()->recordId ) )
|
||||
{
|
||||
$class = 'IPS\cms\Records' . static::$customDatabaseId;
|
||||
$record = $class::load( \IPS\cms\Databases\Dispatcher::i()->recordId );
|
||||
|
||||
if ( $record->_forum_record and $record->_forum_comments and \IPS\Application::appIsEnabled('forums') )
|
||||
{
|
||||
return \IPS\forums\Topic::getCommentsPerPage();
|
||||
}
|
||||
}
|
||||
else if( static::database()->forum_record and static::database()->forum_comments and \IPS\Application::appIsEnabled('forums') )
|
||||
{
|
||||
return \IPS\forums\Topic::getCommentsPerPage();
|
||||
}
|
||||
@@ -215,9 +224,12 @@ class _Records extends \IPS\Content\Item implements
|
||||
|
||||
if ( isset( $qs['path'] ) )
|
||||
{
|
||||
$bits = explode( '/', trim( $qs['path'], '/' ) );
|
||||
$path = array_pop( $bits );
|
||||
|
||||
try
|
||||
{
|
||||
return static::loadFromSlug( $qs['path'], FALSE );
|
||||
return static::loadFromSlug( $path, FALSE );
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
}
|
||||
@@ -320,6 +332,18 @@ class _Records extends \IPS\Content\Item implements
|
||||
return $lang->addToStack( 'content_db_lang_ia_' . static::$customDatabaseId, FALSE );
|
||||
}
|
||||
|
||||
/**
|
||||
* Indefinite Article
|
||||
*
|
||||
* @param \IPS\Lang|NULL $language The language to use, or NULL for the language of the currently logged in member
|
||||
* @return string
|
||||
*/
|
||||
public static function _indefiniteArticle( array $containerData = NULL, \IPS\Lang $lang = NULL )
|
||||
{
|
||||
$lang = $lang ?: \IPS\Member::loggedIn()->language();
|
||||
return $lang->addToStack( 'content_db_lang_ia_' . static::$customDatabaseId, FALSE );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get elements for add/edit form
|
||||
*
|
||||
@@ -774,6 +798,10 @@ class _Records extends \IPS\Content\Item implements
|
||||
|
||||
$thumb = $values['record_image']->thumbnail( 'cms_Records', $fixedFieldSettings['record_image']['thumb_dims'][0], $fixedFieldSettings['record_image']['thumb_dims'][1] );
|
||||
}
|
||||
else
|
||||
{
|
||||
$thumb = $values['record_image'];
|
||||
}
|
||||
|
||||
$this->record_image = (string)$values['record_image'];
|
||||
$this->record_image_thumb = (string)$thumb;
|
||||
@@ -1003,6 +1031,82 @@ class _Records extends \IPS\Content\Item implements
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Columns needed to query for search result / stream view
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function basicDataColumns()
|
||||
{
|
||||
$return = parent::basicDataColumns();
|
||||
$return[] = 'category_id';
|
||||
$return[] = 'record_static_furl';
|
||||
$return[] = 'record_dynamic_furl';
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query to get additional data for search result / stream view
|
||||
*
|
||||
* @param array $items Item data (will be an array containing values from basicDataColumns())
|
||||
* @return array
|
||||
*/
|
||||
public static function searchResultExtraData( $items )
|
||||
{
|
||||
$categoryIds = array();
|
||||
|
||||
foreach ( $items as $item )
|
||||
{
|
||||
if ( $item['category_id'] )
|
||||
{
|
||||
$categoryIds[ $item['category_id'] ] = $item['category_id'];
|
||||
}
|
||||
}
|
||||
|
||||
if ( count( $categoryIds ) )
|
||||
{
|
||||
$categoryPaths = iterator_to_array( \IPS\Db::i()->select( array( 'category_id', 'category_full_path' ), 'cms_database_categories', \IPS\Db::i()->in( 'category_id', $categoryIds ) )->setKeyField('category_id')->setValueField('category_full_path') );
|
||||
|
||||
$return = array();
|
||||
foreach ( $items as $item )
|
||||
{
|
||||
if ( $item['category_id'] )
|
||||
{
|
||||
$return[ $item['primary_id_field'] ] = $categoryPaths[ $item['category_id'] ];
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get URL from index data
|
||||
*
|
||||
* @param array $indexData Data from the search index
|
||||
* @param array $itemData Basic data about the item. Only includes columns returned by item::basicDataColumns()
|
||||
* @return \IPS\Http\Url
|
||||
*/
|
||||
public static function urlFromIndexData( $indexData, $itemData )
|
||||
{
|
||||
if ( static::$pagePath === NULL )
|
||||
{
|
||||
static::$pagePath = \IPS\Db::i()->select( array( 'page_full_path' ), 'cms_pages', array( 'page_id=?', static::database()->page_id ) )->first();
|
||||
}
|
||||
|
||||
$recordSlug = !$itemData['record_static_furl'] ? $itemData['record_dynamic_furl'] . '-r' . $itemData['primary_id_field'] : $itemData['record_static_furl'];
|
||||
|
||||
if ( static::database()->use_categories )
|
||||
{
|
||||
return \IPS\Http\Url::internal( "app=cms&module=pages&controller=page&path=" . static::$pagePath . '/' . $itemData['extra'] . '/' . $recordSlug, 'front', 'content_page_path', $recordSlug );
|
||||
}
|
||||
else
|
||||
{
|
||||
return \IPS\Http\Url::internal( "app=cms&module=pages&controller=page&path=" . static::$pagePath . '/' . $recordSlug, 'front', 'content_page_path', $recordSlug );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Template helper method to fetch custom fields to display
|
||||
@@ -1263,7 +1367,7 @@ class _Records extends \IPS\Content\Item implements
|
||||
*/
|
||||
public function editLine()
|
||||
{
|
||||
if ( static::database()->revisions and $this->record_edit_time and ( $this->record_edit_show or \IPS\Member::loggedIn()->modPermission('can_view_editlog') ) )
|
||||
if ( $this->record_edit_time and ( $this->record_edit_show or \IPS\Member::loggedIn()->modPermission('can_view_editlog') ) and \IPS\Settings::i()->edit_log )
|
||||
{
|
||||
return \IPS\cms\Theme::i()->getTemplate( static::database()->template_display, 'cms', 'database' )->recordEditLine( $this );
|
||||
}
|
||||
@@ -1387,7 +1491,7 @@ class _Records extends \IPS\Content\Item implements
|
||||
/**
|
||||
* Resync the comments/unapproved comment counts
|
||||
*
|
||||
* @param string $commentClass
|
||||
* @param string $commentClass Override comment class to use
|
||||
* @return void
|
||||
*/
|
||||
public function resyncCommentCounts( $commentClass=NULL )
|
||||
@@ -1409,6 +1513,28 @@ class _Records extends \IPS\Content\Item implements
|
||||
parent::resyncCommentCounts( $commentClass );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Are comments supported by this class?
|
||||
*
|
||||
* @param \IPS\Member\NULL $member The member to check for or NULL fto not check permission
|
||||
* @return int
|
||||
*/
|
||||
public static function supportsComments( \IPS\Member $member = NULL )
|
||||
{
|
||||
return parent::supportsComments() and static::database()->options['comments'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Are reviews supported by this class?
|
||||
*
|
||||
* @param \IPS\Member\NULL $member The member to check for or NULL to not check permission
|
||||
* @return int
|
||||
*/
|
||||
public static function supportsReviews( \IPS\Member $member = NULL )
|
||||
{
|
||||
return parent::supportsReviews() and static::database()->options['reviews'];
|
||||
}
|
||||
|
||||
/* !IP.Board Integration */
|
||||
|
||||
@@ -1606,6 +1732,7 @@ class _Records extends \IPS\Content\Item implements
|
||||
}
|
||||
catch( \Exception $ex ) { }
|
||||
}
|
||||
|
||||
return $record;
|
||||
}
|
||||
|
||||
@@ -1617,7 +1744,7 @@ class _Records extends \IPS\Content\Item implements
|
||||
*/
|
||||
public function processAfterEdit( $values )
|
||||
{
|
||||
if ( \IPS\Application::appIsEnabled('forums') and $this->topic() )
|
||||
if ( \IPS\Application::appIsEnabled('forums') and $this->_forum_record and $this->_forum_forum and ! $this->hidden() and ! $this->record_future_date )
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -1684,7 +1811,7 @@ class _Records extends \IPS\Content\Item implements
|
||||
$topic->unhide();
|
||||
}
|
||||
}
|
||||
else if ( $this->_forum_forum )
|
||||
else if ( $this->_forum_forum and $this->_forum_comments )
|
||||
{
|
||||
$this->syncTopic();
|
||||
}
|
||||
@@ -1720,7 +1847,7 @@ class _Records extends \IPS\Content\Item implements
|
||||
{
|
||||
$topic->unhide();
|
||||
}
|
||||
elseif ( $this->_forum_forum )
|
||||
elseif ( $this->_forum_forum and $this->_forum_comments )
|
||||
{
|
||||
$this->syncTopic();
|
||||
}
|
||||
@@ -2370,7 +2497,6 @@ class _Records extends \IPS\Content\Item implements
|
||||
{
|
||||
try
|
||||
{
|
||||
$url = $this->url();
|
||||
return parent::searchIndexPermissions();
|
||||
}
|
||||
catch ( \LogicException $e )
|
||||
|
||||
@@ -0,0 +1,185 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Categories Selector Model
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @since 20 July 2015
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\cms\Selector;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Categories Model
|
||||
*/
|
||||
class _Categories extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
{
|
||||
/**
|
||||
* @brief Multiton Store
|
||||
*/
|
||||
protected static $multitons = array();
|
||||
|
||||
/**
|
||||
* @brief [Records] Custom Database Id
|
||||
*/
|
||||
public static $customDatabaseId = NULL;
|
||||
|
||||
/**
|
||||
* @brief [Records] Content item class
|
||||
*/
|
||||
public static $contentItemClass = NULL;
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Table
|
||||
*/
|
||||
public static $databaseTable = 'cms_database_categories';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Prefix
|
||||
*/
|
||||
public static $databasePrefix = 'category_';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] ID Database Column
|
||||
*/
|
||||
public static $databaseColumnId = 'id';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database ID Fields
|
||||
*/
|
||||
protected static $databaseIdFields = array('category_furl_name', 'category_full_path');
|
||||
|
||||
/**
|
||||
* @brief [Node] Parent ID Database Column
|
||||
*/
|
||||
public static $databaseColumnParent = 'parent_id';
|
||||
|
||||
/**
|
||||
* @brief [Node] Parent ID Database Column
|
||||
*/
|
||||
public static $databaseColumnOrder = 'position';
|
||||
|
||||
/**
|
||||
* @brief [Node] Parent Node ID Database Column
|
||||
*/
|
||||
public static $parentNodeColumnId = 'database_id';
|
||||
|
||||
/**
|
||||
* @brief [Node] Parent Node Class
|
||||
*/
|
||||
public static $parentNodeClass = 'IPS\cms\Selector\Databases';
|
||||
|
||||
/**
|
||||
* @brief [Node] Show forms modally?
|
||||
*/
|
||||
public static $modalForms = FALSE;
|
||||
|
||||
/**
|
||||
* @brief [Node] Sortable?
|
||||
*/
|
||||
public static $nodeSortable = TRUE;
|
||||
|
||||
/**
|
||||
* @brief [Node] Node Title
|
||||
*/
|
||||
public static $nodeTitle = 'r__categories';
|
||||
|
||||
/**
|
||||
* @brief [Node] Title prefix. If specified, will look for a language key with "{$key}_title" as the key
|
||||
*/
|
||||
public static $titleLangPrefix = 'content_cat_name_';
|
||||
|
||||
/**
|
||||
* @brief [Node] Description suffix. If specified, will look for a language key with "{$titleLangPrefix}_{$id}_{$descriptionLangSuffix}" as the key
|
||||
*/
|
||||
public static $descriptionLangSuffix = '_desc';
|
||||
|
||||
/**
|
||||
* @brief [Node] App for permission index
|
||||
*/
|
||||
public static $permApp = 'cms';
|
||||
|
||||
/**
|
||||
* @brief [Node] Type for permission index
|
||||
*/
|
||||
public static $permType = 'categories';
|
||||
|
||||
/**
|
||||
* @brief The map of permission columns
|
||||
*/
|
||||
public static $permissionMap = array(
|
||||
'view' => 'view',
|
||||
'read' => 2,
|
||||
'add' => 3,
|
||||
'edit' => 4,
|
||||
'reply' => 5,
|
||||
'review' => 7,
|
||||
'rate' => 6
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief [Node] Moderator Permission
|
||||
*/
|
||||
public static $modPerm = 'cms';
|
||||
|
||||
/**
|
||||
* @brief [Node] Prefix string that is automatically prepended to permission matrix language strings
|
||||
*/
|
||||
public static $permissionLangPrefix = 'perm_content_';
|
||||
|
||||
/**
|
||||
* Get title of category
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function get__title()
|
||||
{
|
||||
/* If the DB is in a page, and we're not using categories, then return the page title, not the category title for continuity */
|
||||
if ( ! \IPS\cms\Databases::load( $this->database_id )->use_categories )
|
||||
{
|
||||
if ( ! $this->_catTitle )
|
||||
{
|
||||
try
|
||||
{
|
||||
$page = \IPS\cms\Pages\Page::loadByDatabaseId( $this->database_id );
|
||||
$this->_catTitle = $page->_title;
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
{
|
||||
$this->_catTitle = parent::get__title();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_catTitle;
|
||||
}
|
||||
else
|
||||
{
|
||||
return parent::get__title();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Get Description
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
protected function get__description()
|
||||
{
|
||||
if ( ! static::database()->use_categories )
|
||||
{
|
||||
return static::database()->_description;
|
||||
}
|
||||
|
||||
return ( \IPS\Member::loggedIn()->language()->addToStack('content_cat_name_' . $this->id . '_desc') === 'content_cat_name_' . $this->id . '_desc' ) ? $this->description : \IPS\Member::loggedIn()->language()->addToStack('content_cat_name_' . $this->id . '_desc');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Databases Selector Model
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @since 20 July 2015
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\cms\Selector;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Databases Model
|
||||
*/
|
||||
class _Databases extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
{
|
||||
/**
|
||||
* @brief [ActiveRecord] Multiton Store
|
||||
*/
|
||||
protected static $multitons = array();
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Prefix
|
||||
*/
|
||||
public static $databasePrefix = 'database_';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] ID Database Table
|
||||
*/
|
||||
public static $databaseTable = 'cms_databases';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] ID Database Column
|
||||
*/
|
||||
public static $databaseColumnId = 'id';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database ID Fields
|
||||
*/
|
||||
protected static $databaseIdFields = array( 'database_key', 'database_page_id' );
|
||||
|
||||
/**
|
||||
* @brief [Node] Parent ID Database Column
|
||||
*/
|
||||
public static $databaseColumnOrder = 'id';
|
||||
|
||||
/**
|
||||
* @brief [Node] Sortable?
|
||||
*/
|
||||
public static $nodeSortable = FALSE;
|
||||
|
||||
/**
|
||||
* @brief [Node] Node Title
|
||||
*/
|
||||
public static $nodeTitle = '';
|
||||
|
||||
/**
|
||||
* @brief [Node] Subnode class
|
||||
*/
|
||||
public static $subnodeClass = 'IPS\cms\Selector\Categories';
|
||||
|
||||
/**
|
||||
* @brief The map of permission columns
|
||||
*/
|
||||
public static $permissionMap = array(
|
||||
'view' => 'view',
|
||||
'read' => 2,
|
||||
'add' => 3,
|
||||
'edit' => 4,
|
||||
'reply' => 5,
|
||||
'review' => 7,
|
||||
'rate' => 6
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief [Node] App for permission index
|
||||
*/
|
||||
public static $permApp = 'cms';
|
||||
|
||||
/**
|
||||
* @brief [Node] Type for permission index
|
||||
*/
|
||||
public static $permType = 'databases';
|
||||
|
||||
/**
|
||||
* @brief [Node] Prefix string that is automatically prepended to permission matrix language strings
|
||||
*/
|
||||
public static $permissionLangPrefix = 'perm_content_';
|
||||
|
||||
/**
|
||||
* @brief [Node] Title prefix. If specified, will look for a language key with "{$titleLangPrefix}_{$id}" as the key
|
||||
*/
|
||||
public static $titleLangPrefix = 'content_db_';
|
||||
|
||||
/**
|
||||
* @brief [Node] Description suffix. If specified, will look for a language key with "{$titleLangPrefix}_{$id}_{$descriptionLangSuffix}" as the key
|
||||
*/
|
||||
public static $descriptionLangSuffix = 'desc';
|
||||
}
|
||||
@@ -91,7 +91,7 @@ class _Templates extends \IPS\Patterns\ActiveRecord
|
||||
/**
|
||||
* @brief Return both IN_DEV and database templates
|
||||
*/
|
||||
const RETURN_DATABASE_AND_IN_DEV = 128;
|
||||
const RETURN_DATABASE_AND_IN_DEV = 256;
|
||||
|
||||
/**
|
||||
* Load Record
|
||||
@@ -235,7 +235,7 @@ class _Templates extends \IPS\Patterns\ActiveRecord
|
||||
$return = array();
|
||||
$locations = NULL;
|
||||
|
||||
if ( ( \IPS\IN_DEV or \IPS\Theme::designersModeEnabled() ) AND ! ( $returnType & self::RETURN_DATABASE_ONLY ) )
|
||||
if ( ( \IPS\IN_DEV or \IPS\Theme::designersModeEnabled() ) AND ( $returnType & self::RETURN_DATABASE_AND_IN_DEV ) AND ! ( $returnType & self::RETURN_DATABASE_ONLY ) )
|
||||
{
|
||||
$flags = \IPS\cms\Theme::RETURN_AS_OBJECT;
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ class _Theme extends \IPS\cms\Theme
|
||||
|
||||
foreach( new \DirectoryIterator( $path . '/' . $group->getFilename() ) as $file )
|
||||
{
|
||||
if ( $file->isDot() || mb_substr( $file->getFilename(), -6 ) !== '.phtml')
|
||||
if ( $file->isDot() || ( mb_substr( $file->getFilename(), -6 ) !== '.phtml' and mb_substr( $file->getFilename(), -3 ) !== '.js' and mb_substr( $file->getFilename(), -4 ) !== '.css' ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -108,7 +108,7 @@ class _Theme extends \IPS\cms\Theme
|
||||
$html = file_get_contents( $path . '/' . $group->getFilename() . '/' . $file->getFilename() );
|
||||
|
||||
/* Parse the header tag */
|
||||
preg_match( '/^<ips:template parameters="(.+?)?"([^>]+?)>(\r\n?|\n)/', $html, $params );
|
||||
preg_match( '/^<ips:template parameters="([^"]+?)?"([^>]+?)>(\r\n?|\n)/', $html, $params );
|
||||
|
||||
/* Strip it */
|
||||
$html = ( isset($params[0]) ) ? str_replace( $params[0], '', $html ) : $html;
|
||||
@@ -117,7 +117,7 @@ class _Theme extends \IPS\cms\Theme
|
||||
|
||||
if ( isset( $params[2] ) and mb_stristr( $params[2], 'original_group' ) )
|
||||
{
|
||||
preg_match( '#original_group="(.+?)"#', $params[2], $submatches );
|
||||
preg_match( '#original_group="(.+?)?"#', $params[2], $submatches );
|
||||
|
||||
if ( isset( $submatches[1] ) )
|
||||
{
|
||||
@@ -133,7 +133,7 @@ class _Theme extends \IPS\cms\Theme
|
||||
|
||||
if ( isset( $templates[ $key ] ) )
|
||||
{
|
||||
if ( md5( trim( $templates[ $key ]['template_content'] ) ) == md5( trim( $html ) ) )
|
||||
if ( md5( trim( $templates[ $key ]['template_content'] ) ) == md5( trim( $html ) ) and 1==2 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -144,8 +144,9 @@ class _Theme extends \IPS\cms\Theme
|
||||
{
|
||||
$added = TRUE;
|
||||
\IPS\Db::i()->update( 'cms_templates', array(
|
||||
'template_content' => $html,
|
||||
'template_params' => ( isset($params[1]) ) ? $params[1] : '',
|
||||
'template_content' => $html,
|
||||
'template_params' => ( isset($params[1]) ) ? $params[1] : '',
|
||||
'template_file_object' => NULL
|
||||
), array( 'template_id=?', $templates[ $key ]['template_id'] ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -256,7 +256,7 @@ class _Theme extends \IPS\Theme
|
||||
}
|
||||
else
|
||||
{
|
||||
@chmod( $path . '/' . $template['template_location'] . '/' . $template['template_group'] . '/' . $fileName, 0777 );
|
||||
@chmod( $path . '/' . $template['template_location'] . '/' . $template['template_group'] . '/' . $fileName, \IPS\IPS_FILE_PERMISSION );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -280,7 +280,7 @@ class _Theme extends \IPS\Theme
|
||||
$where = array();
|
||||
$templates = array();
|
||||
|
||||
if ( ( \IPS\IN_DEV or \IPS\Theme::designersModeEnabled() ) AND ! ( $returnType & static::RETURN_DATABASE_ONLY ) )
|
||||
if ( ( \IPS\IN_DEV or \IPS\Theme::designersModeEnabled() ) AND ! ( $returnType ^ static::RETURN_DATABASE_ONLY ) )
|
||||
{
|
||||
$fixedLocations = array( 'admin', 'front', 'global' );
|
||||
$results = array();
|
||||
@@ -342,7 +342,7 @@ class _Theme extends \IPS\Theme
|
||||
|
||||
$contents = file_get_contents( static::_getHtmlPath( 'cms', $location->getFilename(), $file->getFilename() ) . '/' . $template->getFilename() );
|
||||
$key = \IPS\cms\Theme\Template::extractDataFromTag( $contents, 'key' );
|
||||
$key = $key ? $key : \IPS\Http\Url::seoTitle( $title );
|
||||
$key = $key ? $key : \IPS\Http\Url::seoTitle( $file->getFilename() . '_' . $title );
|
||||
$ogroup = \IPS\cms\Theme\Template::extractDataFromTag( $contents, 'original_group' );
|
||||
$params = \IPS\cms\Theme\Template::extractParamsFromTag( $contents );
|
||||
$container = NULL;
|
||||
|
||||
Reference in new issue
Block a user