Version 4.0.13.1

This commit is contained in:
Neo committed 2025-12-19 04:57:54 -08:00
1 parent f9e857d255
commit c6a86f0d9b
7517 files changed
+597400 -668041

No files matched your search

@@ -0,0 +1,156 @@
<?php
/**
* @brief Customization AJAX actions
* @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 May 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\cms\modules\admin\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;
}
/**
* Members AJAX actions
*/
class _ajax extends \IPS\Dispatcher\Controller
{
/**
* Return a CSS or HTML menu
*
* @return html
*/
public function loadMenu()
{
$request = array(
't_location' => ( isset( \IPS\Request::i()->t_location ) ) ? \IPS\Request::i()->t_location : null,
't_group' => ( isset( \IPS\Request::i()->t_group ) ) ? \IPS\Request::i()->t_group : null,
't_key' => ( isset( \IPS\Request::i()->t_key ) ) ? \IPS\Request::i()->t_key : null,
't_type' => ( isset( \IPS\Request::i()->t_type ) ) ? \IPS\Request::i()->t_type : 'templates',
);
switch( $request['t_type'] )
{
default:
case 'template':
$flag = \IPS\cms\Templates::RETURN_ONLY_TEMPLATE;
break;
case 'js':
$flag = \IPS\cms\Templates::RETURN_ONLY_JS;
break;
case 'css':
$flag = \IPS\cms\Templates::RETURN_ONLY_CSS;
break;
}
$templates = \IPS\cms\Templates::buildTree( \IPS\cms\Templates::getTemplates( $flag + \IPS\cms\Templates::RETURN_DATABASE_ONLY ) );
$current = new \IPS\cms\Templates;
if ( ! empty( $request['t_key'] ) )
{
try
{
$current = \IPS\cms\Templates::load( $request['t_key'] );
}
catch( \OutOfRangeException $ex )
{
}
}
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'templates' )->menu( $templates, $current, $request );
}
/**
* Return HTML template as JSON
*
* @return string
*/
public function loadTemplate()
{
$t_location = \IPS\Request::i()->t_location;
$t_key = \IPS\Request::i()->t_key;
if ( $t_location === 'block' and $t_key === '_default_' and isset( \IPS\Request::i()->block_key ) )
{
/* Find it from the normal template system */
$plugin = \IPS\Widget::load( \IPS\Application::load( \IPS\Request::i()->block_app ), \IPS\Request::i()->block_key, uniqid() );
$location = $plugin->getTemplateLocation();
$templateBits = \IPS\Theme::master()->getRawTemplates( $location['app'], $location['location'], $location['group'], \IPS\Theme::RETURN_ALL );
$templateBit = $templateBits[ $location['app'] ][ $location['location'] ][ $location['group'] ][ $location['name'] ];
$templateBit['template_content'] = htmlentities( $templateBit['template_content'], \IPS\HTMLENTITIES, 'UTF-8', TRUE );
$templateArray = array(
'template_id' => $templateBit['template_id'],
'template_key' => 'template_' . $templateBit['template_name'] . '.' . $templateBit['template_id'],
'template_title' => $templateBit['template_name'],
'template_desc' => null,
'template_content' => $templateBit['template_content'],
'template_location' => null,
'template_group' => null,
'template_container' => null,
'template_rel_id' => null,
'template_user_created' => null,
'template_user_edited' => null,
'template_params' => $templateBit['template_data']
);
}
else
{
try
{
if ( is_numeric( $t_key ) )
{
$template = \IPS\cms\Templates::load( $t_key, 'template_id' );
}
else
{
$template = \IPS\cms\Templates::load( $t_key );
}
}
catch( \OutOfRangeException $ex )
{
\IPS\Output::i()->json( array( 'error' => true ) );
}
if ( $template !== null )
{
$templateArray = array(
'template_id' => $template->id,
'template_key' => $template->key,
'template_title' => $template->title,
'template_desc' => $template->desc,
'template_content' => htmlentities( $template->content, \IPS\HTMLENTITIES, 'UTF-8', TRUE ),
'template_location' => $template->location,
'template_group' => $template->group,
'template_container' => $template->container,
'template_rel_id' => $template->rel_id,
'template_user_created' => $template->user_created,
'template_user_edited' => $template->user_edited,
'template_params' => $template->params
);
}
}
if ( \IPS\Request::i()->show == 'json' )
{
\IPS\Output::i()->json( $templateArray );
}
else
{
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->blankTemplate( \IPS\Theme::i()->getTemplate( 'templates', 'cms', 'admin' )->viewTemplate( $templateArray ) ), 200, 'text/html', \IPS\Output::i()->httpHeaders );
}
}
}
@@ -0,0 +1,183 @@
<?php
/**
* @brief Block Controller
* @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 19 Feb 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\cms\modules\admin\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;
}
/**
* blocks
*/
class _blocks extends \IPS\Node\Controller
{
/**
* Node Class
*/
protected $nodeClass = '\IPS\cms\Blocks\Container';
/**
* Execute
*
* @return void
*/
public function execute()
{
\IPS\Dispatcher::i()->checkAcpPermission( 'block_manage' );
parent::execute();
}
/**
* Manage
*
* @return void
*/
public function manage()
{
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__cms_pages_blocks');
parent::manage();
}
/**
* Delete
*
* @return void
*/
protected function delete()
{
if ( isset( \IPS\Request::i()->id ) )
{
\IPS\cms\Blocks\Block::deleteCompiled( \IPS\Request::i()->id );
}
parent::delete();
}
/**
* Get Root Buttons
*
* @return array
*/
public function _getRootButtons()
{
$nodeClass = $this->nodeClass;
$buttons = array();
if ( $nodeClass::canAddRoot() )
{
$buttons['add_meow'] = array(
'icon' => 'plus',
'title' => 'content_block_cat_add',
'link' => $this->url->setQueryString( 'do', 'form' ),
'data' => ( $nodeClass::$modalForms ? array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('content_block_cat_add') ) : array() )
);
}
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'cms', 'pages', 'block_add' ) )
{
$buttons['add_block'] = array(
'icon' => 'puzzle-piece',
'title' => 'content_block_block_add',
'link' => $this->url->setQueryString( array( 'do' => 'addBlockType', 'subnode' => 1 ) ),
'data' => ( $nodeClass::$modalForms ? array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('content_block_block_add') ) : array() )
);
}
return $buttons;
}
/**
* Add block, pre form
*
* @return void
*/
public function addBlockType()
{
\IPS\Dispatcher::i()->checkAcpPermission( 'block_add' );
$form = new \IPS\Helpers\Form( 'block_add_first_step', 'next');
$form->add( new \IPS\Helpers\Form\Radio( 'content_block_add_type', 'plugin', FALSE, array(
'options' => array(
'plugin' => 'content_block_add_type_plugin',
'custom' => 'content_block_add_type_custom'
),
'toggles' => array(
'plugin' => array( 'content_block_add_type_plugin' ),
'custom' => array( 'content_block_add_custom_type' )
)
)
) );
$plugins = array();
foreach ( \IPS\Db::i()->select( "*", 'core_widgets', array( 'embeddable=1') ) as $widget )
{
try
{
if ( $widget['app'] )
{
$plugins[ \IPS\Application::load( $widget['app'] )->_title ][ 'app__' . $widget['app'] . '__' . $widget['key'] ] = \IPS\Member::loggedIn()->language()->addToStack( 'block_' . $widget['key'] );
}
else
{
$plugins[ \IPS\Plugin::load( $widget['plugin'] )->_title ][ 'plugin__' . $widget['plugin'] . '__' . $widget['key'] ] = \IPS\Member::loggedIn()->language()->addToStack( 'block_' . $widget['key'] );
}
}
catch ( \OutOfRangeException $e ) { }
}
foreach( \IPS\cms\Databases::databases() as $db )
{
if ( $db->page_id )
{
$plugins[ \IPS\Member::loggedIn()->language()->addToStack( 'cms_db_feed_title' ) ][ 'db_feed_' . $db->id ] = \IPS\Member::loggedIn()->language()->addToStack( 'cms_db_feed_block_with_name', NULL, array( 'sprintf' => array( $db->_title ) ) );
}
}
$form->add( new \IPS\Helpers\Form\Select( 'content_block_add_type_plugin', null, false, array( 'options' => $plugins ), NULL, NULL, NULL, 'content_block_add_type_plugin' ) );
$form->add( new \IPS\Helpers\Form\Radio( 'content_block_add_custom_type', 'editor', TRUE, array(
'options' => array( 'editor' => 'content_block_add_custom_type_wysiwyg',
'html' => 'content_block_add_custom_type_html',
'php' => 'content_block_add_custom_type_php'
) ), NULL, NULL, NULL, 'content_block_add_custom_type' ) );
if ( $values = $form->values() )
{
if ( $values['content_block_add_type'] !== 'custom' )
{
if ( mb_substr( $values['content_block_add_type_plugin'], 0, 8 ) === 'db_feed_' )
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=cms&module=pages&controller=blocks&do=form&subnode=1&block_type=plugin&block_plugin=' . $values['content_block_add_type_plugin'] . '&block_plugin_app=cms&parent=' . \IPS\Request::i()->parent ) );
}
else
{
list( $type, $value, $key ) = explode( '__', $values['content_block_add_type_plugin'] );
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=cms&module=pages&controller=blocks&do=form&subnode=1&block_type=plugin&block_plugin=' . $key . "&block_plugin_{$type}={$value}" . '&parent=' . \IPS\Request::i()->parent ) );
}
}
else
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=cms&module=pages&controller=blocks&do=form&subnode=1&block_type=' . $values['content_block_add_type'] . '&block_editor=' . $values['content_block_add_custom_type'] . '&parent=' . \IPS\Request::i()->parent ) );
}
}
/* Display */
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'global', 'core', 'admin' )->block( \IPS\Member::loggedIn()->language()->addToStack('content_block_block_add'), $form, FALSE );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('content_block_block_add');
}
}
Whitespace-only changes.
@@ -0,0 +1,69 @@
<?php
/**
* @brief Page menu Controller
* @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\modules\admin\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;
}
/**
* Page management
*/
class _menu extends \IPS\Node\Controller
{
/**
* Node Class
*/
protected $nodeClass = '\IPS\cms\Pages\Menu';
/**
* Execute
*
* @return void
*/
public function execute()
{
\IPS\Dispatcher::i()->checkAcpPermission( 'menu_manage' );
parent::execute();
}
/**
* Show the pages tree
*
* @return string
*/
protected function manage()
{
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__cms_pages_menu');
if ( ! \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->message( \IPS\Member::loggedIn()->language()->addToStack('cms_menu_information'), 'information', NULL, FALSE );
}
return parent::manage();
}
/**
* Delete
*
* @return void
*/
protected function delete()
{
unset( \IPS\Data\Store::i()->cms_menu );
parent::delete();
}
}
@@ -0,0 +1,432 @@
<?php
/**
* @brief Pages Controller
* @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 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\cms\modules\admin\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;
}
/**
* Page management
*/
class _pages extends \IPS\Node\Controller
{
/**
* Node Class
*/
protected $nodeClass = '\IPS\cms\Pages\Folder';
/**
* Execute
*
* @return void
*/
public function execute()
{
\IPS\Dispatcher::i()->checkAcpPermission( 'page_manage' );
parent::execute();
}
/**
* Get Root Buttons
*
* @return array
*/
public function _getRootButtons()
{
$nodeClass = $this->nodeClass;
$buttons = array();
if ( \IPS\Member::loggedIn()->hasAcpRestriction( 'cms', 'pages', 'page_add' ) )
{
$buttons['add_folder'] = array(
'icon' => 'folder-open',
'title' => 'content_add_folder',
'link' => \IPS\Http\Url::internal( 'app=cms&module=pages&controller=pages&do=form' ),
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('content_add_folder') )
);
$buttons['add_page'] = array(
'icon' => 'plus-circle',
'title' => 'content_add_page',
'link' => \IPS\Http\Url::internal( 'app=cms&module=pages&controller=pages&subnode=1&do=add' ),
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('content_add_page') )
);
}
return $buttons;
}
/**
* Show the pages tree
*
* @return string
*/
protected function manage()
{
$url = \IPS\Http\Url::internal( "app=cms&module=pages&controller=pages" );
/* Display the table */
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__cms_pages_pages');
\IPS\Output::i()->output = new \IPS\Helpers\Tree\Tree( $url, 'menu__cms_pages_pages',
/* Get Roots */
function () use ( $url )
{
$data = \IPS\cms\modules\admin\pages\pages::getRowsForTree( 0 );
$rows = array();
foreach ( $data as $id => $row )
{
$rows[ $id ] = ( $row instanceof \IPS\cms\Pages\Page ) ? \IPS\cms\modules\admin\pages\pages::getPageRow( $row, $url ) : \IPS\cms\modules\admin\pages\pages::getFolderRow( $row, $url );
}
return $rows;
},
/* Get Row */
function ( $id, $root ) use ( $url )
{
if ( $root )
{
return \IPS\cms\modules\admin\pages\pages::getFolderRow( \IPS\cms\Pages\Folder::load( $id ), $url );
}
else
{
return \IPS\cms\modules\admin\pages\pages::getPageRow( \IPS\cms\Pages\Page::load( $id ), $url );
}
},
/* Get Row Parent ID*/
function ()
{
return NULL;
},
/* Get Children */
function ( $id ) use ( $url )
{
$rows = array();
$data = \IPS\cms\modules\admin\pages\pages::getRowsForTree( $id );
if ( ! isset( \IPS\Request::i()->subnode ) )
{
foreach ( $data as $id => $row )
{
$rows[ $id ] = ( $row instanceof \IPS\cms\Pages\Page ) ? \IPS\cms\modules\admin\pages\pages::getPageRow( $row, $url ) : \IPS\cms\modules\admin\pages\pages::getFolderRow( $row, $url );
}
}
return $rows;
},
array( $this, '_getRootButtons' ),
TRUE,
FALSE,
FALSE
);
/* Add a button for managing DB settings */
\IPS\Output::i()->sidebar['actions']['pagessettings'] = array(
'title' => 'cms_pages_settings',
'icon' => 'wrench',
'link' => \IPS\Http\Url::internal( 'app=cms&module=pages&controller=pages&do=settings' ),
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('cms_pages_settings') )
);
}
/**
* Page settings form
*
* @return void
*/
protected function settings()
{
$url = parse_url( \IPS\Settings::i()->base_url );
$disabled = FALSE;
$options = array();
$url['path'] = preg_replace( '#^/?(.+?)?/?$#', '\1', $url['path'] );
$disabled = ( $url['path'] ) ? FALSE : TRUE;
$dirs = explode( '/', $url['path'] );
if ( count( $dirs ) )
{
array_pop( $dirs );
$base = $url['scheme'] . '://' . $url['host'];
if ( isset( $url['port'] ) )
{
$base .= ':' .$url['port'];
}
$base .= '/';
$options[ $base ] = $base;
foreach( $dirs as $dir )
{
$base .= $dir . '/';
$options[ $base ] = $base;
}
}
if ( $disabled )
{
\IPS\Member::loggedIn()->language()->words['cms_use_different_gateway_warning'] = \IPS\Member::loggedIn()->language()->addToStack('cms_pages_different_gateway_impossible');
}
if ( \IPS\Settings::i()->htaccess_mod_rewrite )
{
\IPS\Member::loggedIn()->language()->words['cms_root_page_url_desc'] = \IPS\Member::loggedIn()->language()->addToStack('cms_root_page_url_rewrite_desc');
}
$form = new \IPS\Helpers\Form( 'form', 'save' );
$form->add( new \IPS\Helpers\Form\YesNo( 'cms_use_different_gateway', \IPS\Settings::i()->cms_use_different_gateway, FALSE, array( 'togglesOn' => array( 'cms_root_page_url' ), 'disabled' => $disabled ) ) );
$form->add( new \IPS\Helpers\Form\Select( 'cms_root_page_url', \IPS\Settings::i()->cms_root_page_url, FALSE, array( 'options' => $options ), function( $val )
{
if ( $val and \IPS\Request::i()->cms_use_different_gateway )
{
if ( mb_substr( $val, -1 ) !== '/' )
{
$val .= '/';
}
$page = \IPS\cms\Pages\Page::getDefaultPage();
$response = \IPS\Http\Url::external( ( \IPS\Settings::i()->htaccess_mod_rewrite ? $val . $page->full_path : $val . 'index.php?/' . $page->full_path ) )->request( 5, '1.1', FALSE )->get();
if ( $response->httpResponseCode != 200 and $response->httpResponseCode != 303 and ( \IPS\Settings::i()->site_online OR $response->httpResponseCode != 503 ) )
{
if ( \IPS\Settings::i()->htaccess_mod_rewrite )
{
throw new \LogicException( 'pages_different_gateway_load_error_rewrite' );
}
else
{
throw new \LogicException( 'pages_different_gateway_load_error' );
}
}
}
}, NULL, NULL, 'cms_root_page_url' ) );
if ( $values = $form->values() )
{
$form->saveAsSettings();
\IPS\Member::clearCreateMenu();
\IPS\cms\Pages\Menu::clearCaches();
/* Clear Sidebar Caches */
\IPS\Widget::deleteCaches();
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=cms&module=pages&controller=pages" ), 'saved' );
}
/* Display */
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'global', 'core', 'admin' )->block( \IPS\Member::loggedIn()->language()->addToStack('cms_pages_settings'), $form, FALSE );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('cms_pages_settings');
}
/**
* Download .htaccess file
*
* @return void
*/
protected function htaccess()
{
$dir = str_replace( \IPS\CP_DIRECTORY . '/index.php', '', $_SERVER['PHP_SELF'] );
$path = $dir . 'index.php';
if( \strpos( $dir, ' ' ) !== FALSE )
{
$dir = '"' . $dir . '"';
$path = '"' . $path . '"';
}
$htaccess = <<<FILE
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
RewriteBase {$dir}
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule \\.(js|css|jpeg|jpg|gif|png|ico)(\\?|$) - [L,NC,R=404]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . {$path} [L]
</IfModule>
FILE;
\IPS\Output::i()->sendOutput( $htaccess, 200, 'application/x-htaccess', array( 'Content-Disposition' => 'attachment; filename=.htaccess' ) );
}
/**
* Page content form
*
* @return void
*/
protected function add()
{
\IPS\Dispatcher::i()->checkAcpPermission( 'page_add' );
$form = new \IPS\Helpers\Form( 'form', 'next' );
$form->hiddenValues['parent'] = ( isset( \IPS\Request::i()->parent ) ) ? \IPS\Request::i()->parent : 0;
$form->add( new \IPS\Helpers\Form\Radio(
'page_type',
NULL,
FALSE,
array( 'options' => array( 'builder' => 'page_type_builder', 'html' => 'page_type_manual' ),
'descriptions' => array( 'builder' => 'page_type_builder_desc', 'html' => 'page_type_manual_custom_desc' ) ),
NULL,
NULL,
NULL,
'page_type'
) );
if ( $values = $form->values() )
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=cms&module=pages&controller=pages&do=form&subnode=1&page_type=' . $values['page_type'] . '&parent=' . \IPS\Request::i()->parent ) );
}
/* Display */
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'global', 'core', 'admin' )->block( \IPS\Member::loggedIn()->language()->addToStack('content_add_page'), $form, FALSE );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('content_add_page');
}
/**
* Delete
*
* @return void
*/
protected function delete()
{
if ( isset( \IPS\Request::i()->id ) )
{
\IPS\cms\Pages\Page::deleteCompiled( \IPS\Request::i()->id );
}
parent::delete();
}
/**
* Set as default page for this folder
*
* @return void
*/
protected function setAsDefault()
{
\IPS\cms\Pages\Page::load( \IPS\Request::i()->id )->setAsDefault();
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=cms&module=pages&controller=pages" ), 'saved' );
}
/**
* Tree Search
*
* @return void
*/
protected function search()
{
$rows = array();
$url = \IPS\Http\Url::internal( "app=cms&module=pages&controller=pages" );
/* Get results */
$folders = \IPS\cms\Pages\Folder::search( 'folder_name' , \IPS\Request::i()->input, 'folder_name' );
$pages = \IPS\cms\Pages\Page::search( 'page_seo_name', \IPS\Request::i()->input, 'page_seo_name' );
$results = \IPS\cms\Pages\Folder::munge( $folders, $pages );
/* Convert to HTML */
foreach ( $results as $id => $result )
{
$rows[ $id ] = ( $result instanceof \IPS\cms\Pages\Page ) ? $this->_getPageRow( $result, $url ) : $this->_getFolderRow( $result, $url );
}
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'trees', 'core' )->rows( $rows, '' );
}
/**
* Return HTML for a page row
*
* @param array $row Row data
* @param object $url \IPS\Http\Url object
* @return string HTML
*/
public static function getPageRow( $page, $url )
{
return \IPS\Theme::i()->getTemplate( 'trees', 'core' )->row( $url, $page->id, $page->seo_name, false, $page->getButtons( \IPS\Http\url::internal('app=cms&module=pages&controller=pages'), true ), "", 'file-text-o', NULL, FALSE, NULL, NULL, NULL, FALSE, FALSE, FALSE );
}
/**
* Return HTML for a folder row
*
* @param array $row Row data
* @param object $url \IPS\Http\Url object
* @return string HTML
*/
public static function getFolderRow( $folder, $url )
{
return \IPS\Theme::i()->getTemplate( 'trees', 'core' )->row( $url, $folder->id, $folder->name, true, $folder->getButtons( \IPS\Http\url::internal('app=cms&module=pages&controller=pages') ), "", 'folder-o', NULL );
}
/**
* Fetch rows of folders/pages
*
* @param int $folderId Parent ID to fetch from
*/
public static function getRowsForTree( $folderId=0 )
{
try
{
if ( $folderId === 0 )
{
$folders = \IPS\cms\Pages\Folder::roots();
}
else
{
$folders = \IPS\cms\Pages\Folder::load( $folderId )->children( NULL, NULL, FALSE );
}
}
catch( \OutOfRangeException $ex )
{
$folders = array();
}
$pages = \IPS\cms\Pages\Page::getChildren( $folderId );
return \IPS\cms\Pages\Folder::munge( $folders, $pages );
}
/**
* Redirect after save
*
* @param \IPS\Node\Model $old A clone of the node as it was before or NULL if this is a creation
* @param \IPS\Node\Model $node The node now
* @return void
*/
protected function _afterSave( \IPS\Node\Model $old = NULL, \IPS\Node\Model $new )
{
if( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->json( array() );
}
else
{
if( isset( \IPS\Request::i()->save_and_reload ) )
{
$buttons = $new->getButtons( $this->url, !( $new instanceof $this->nodeClass ) );
\IPS\Output::i()->redirect( $buttons['edit']['link'], 'saved' );
}
else
{
\IPS\Output::i()->redirect( $this->url->setQueryString( array( 'root' => ( $new->parent() ? $new->parent()->_id : '' ) ) ), 'saved' );
}
}
}
}
@@ -0,0 +1,583 @@
<?php
/**
* @brief Templates Controller
* @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 25 Feb 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\cms\modules\admin\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;
}
/**
* templates
*/
class _templates extends \IPS\Dispatcher\Controller
{
/**
* Execute
*
* @return void
*/
public function execute()
{
\IPS\Dispatcher::i()->checkAcpPermission( 'template_manage' );
parent::execute();
}
/**
* Import the IN_DEV templates
*
* @return void
*/
public function importInDev()
{
\IPS\cms\Theme::importInDev('database');
\IPS\cms\Theme::importInDev('page');
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=cms&module=pages&controller=templates' ), 'completed' );
}
/**
* List templates
*
* @return void
*/
public function manage()
{
\IPS\Dispatcher::i()->checkAcpPermission( 'template_add_edit' );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__cms_pages_templates');
if ( \IPS\Theme::designersModeEnabled() )
{
$link = \IPS\Http\Url::internal( 'app=core&module=customization&controller=themes&do=designersmode' );
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->message( \IPS\Member::loggedIn()->language()->addToStack('cms_theme_designer_mode_warning', NULL, array( 'sprintf' => array( $link ) ) ), 'information', NULL, FALSE );
}
else
{
$request = array(
't_location' => ( isset( \IPS\Request::i()->t_location ) ) ? \IPS\Request::i()->t_location : NULL,
't_group' => ( isset( \IPS\Request::i()->t_group ) ) ? \IPS\Request::i()->t_group : NULL,
't_key' => ( isset( \IPS\Request::i()->t_key ) ) ? \IPS\Request::i()->t_key : NULL,
't_type' => ( isset( \IPS\Request::i()->t_type ) ) ? \IPS\Request::i()->t_type : 'templates',
);
switch ( $request['t_type'] )
{
default:
case 'template':
$flag = \IPS\cms\Templates::RETURN_ONLY_TEMPLATE;
break;
case 'js':
$flag = \IPS\cms\Templates::RETURN_ONLY_JS;
break;
case 'css':
$flag = \IPS\cms\Templates::RETURN_ONLY_CSS;
break;
}
$templates = \IPS\cms\Templates::buildTree( \IPS\cms\Templates::getTemplates( $flag + \IPS\cms\Templates::RETURN_DATABASE_ONLY ) );
$current = NULL;
if ( !empty( $request['t_key'] ) )
{
try
{
$current = \IPS\cms\Templates::load( $request['t_key'] );
}
catch ( \OutOfRangeException $ex )
{
}
}
/* Load first block */
if ( $current === NULL )
{
foreach ( $templates as $type => $_templates )
{
if ( $_templates )
{
$test = key( $_templates );
try
{
$current = \IPS\cms\Templates::load( $test );
}
catch ( \OutofRangeException $e )
{
foreach ( $_templates as $location => $group )
{
foreach ( $group as $name => $template )
{
$current = $template;
break 3;
}
}
}
}
}
}
/* Display */
\IPS\Output::i()->responsive = FALSE;
/* A button */
if ( \IPS\IN_DEV )
{
\IPS\Output::i()->sidebar['actions']['add'] = array(
'icon' => 'cog',
'title' => 'content_import_dev_templates',
'link' => \IPS\Http\Url::internal( "app=cms&module=pages&controller=templates&do=importInDev" ),
'data' => array()
);
}
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'codemirror/diff_match_patch.js', 'core', 'interface' ) );
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'codemirror/codemirror.js', 'core', 'interface' ) );
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'codemirror/codemirror.css', 'core', 'interface' ) );
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'templates/templates.css', 'cms', 'admin' ) );
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'admin_templates.js', 'cms' ) );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'templates' )->templates( $templates, $current, $request );
}
}
/**
* Add Container
*
* @return void
*/
public function addContainer()
{
/* Check permission */
\IPS\Dispatcher::i()->checkAcpPermission( 'template_add' );
$type = \IPS\Request::i()->type;
/* Build form */
$form = new \IPS\Helpers\Form();
$form->add( new \IPS\Helpers\Form\Text( 'container_name', NULL, TRUE ) );
$form->hiddenValues['type'] = $type;
if ( $values = $form->values() )
{
$type = \IPS\Request::i()->type;
$newContainer = \IPS\cms\Templates\Container::add( array(
'name' => $values['container_name'],
'type' => 'template_' . $type
) );
if( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->json( array(
'id' => $newContainer->id,
'name' => $newContainer->title,
) );
}
else
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=cms&module=pages&controller=templates' ), 'saved' );
}
}
/* Display */
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->block( 'content_template_add_container_' . $type, $form, FALSE );
}
/**
* Add Template
* This is never used for editing as this is done via the template manager
*
* @return void
*/
public function addTemplate()
{
/* Check permission */
\IPS\Dispatcher::i()->checkAcpPermission( 'template_add' );
$type = \IPS\Request::i()->type;
/* Build form */
$form = new \IPS\Helpers\Form();
$form->hiddenValues['type'] = $type;
$form->add( new \IPS\Helpers\Form\Text( 'template_title', NULL, TRUE ) );
/* Very specific */
if ( $type === 'database' )
{
$groups = array(); /* I was sorely tempted to put 'Radiohead', 'Beatles' in there */
foreach( \IPS\cms\Databases::$templateGroups as $key => $group )
{
$groups[ $key ] = \IPS\Member::loggedIn()->language()->addToStack( 'cms_new_db_template_group_' . $key );
}
$form->add( new \IPS\Helpers\Form\Select( 'database_template_type', NULL, FALSE, array(
'options' => $groups
) ) );
$databases = array( 0 => \IPS\Member::loggedIn()->language()->addToStack('cms_new_db_assign_to_db_none' ) );
foreach( \IPS\cms\Databases::databases() as $obj )
{
$databases[ $obj->id ] = $obj->_title;
}
$form->add( new \IPS\Helpers\Form\Select( 'database_assign_to', NULL, FALSE, array(
'options' => $databases
) ) );
}
else if ( $type === 'block' )
{
$plugins = array();
foreach ( \IPS\Db::i()->select( "*", 'core_widgets', array( 'embeddable=1') ) as $widget )
{
try
{
$plugins[ \IPS\Application::load( $widget['app'] )->_title ][ $widget['app'] . '__' . $widget['key'] ] = \IPS\Member::loggedIn()->language()->addToStack( 'block_' . $widget['key'] );
}
catch ( \OutOfRangeException $e ) { }
}
$form->add( new \IPS\Helpers\Form\Select( 'block_template_plugin_import', NULL, FALSE, array(
'options' => $plugins
) ) );
$form->add( new \IPS\Helpers\Form\Node( 'block_template_theme_import', NULL, TRUE, array(
'class' => '\IPS\Theme'
) ) );
}
else
{
/* Page, css, js */
switch( $type )
{
default:
$flag = \IPS\cms\Theme::RETURN_ONLY_TEMPLATE;
break;
case 'page':
$flag = \IPS\cms\Theme::RETURN_PAGE;
break;
case 'js':
$flag = \IPS\cms\Theme::RETURN_ONLY_JS;
break;
case 'css':
$flag = \IPS\cms\Theme::RETURN_ONLY_CSS;
break;
}
$templates = \IPS\cms\Theme::i()->getRawTemplates( array(), array(), array(), $flag | \IPS\cms\Theme::RETURN_ALL_NO_CONTENT );
$groups = array();
if ( isset( $templates['cms'][ $type ] ) )
{
foreach( $templates['cms'][ $type ] as $group => $data )
{
$groups[ $group ] = \IPS\cms\Templates::readableGroupName( $group );
}
}
if ( ! count( $groups ) )
{
$groups[ $type ] = \IPS\cms\Templates::readableGroupName( $type );
}
$form->add( new \IPS\Helpers\Form\Radio( 'theme_template_group_type', 'existing', FALSE, array(
'options' => array( 'existing' => 'theme_template_group_o_existing',
'new' => 'theme_template_group_o_new' ),
'toggles' => array( 'existing' => array( 'group_existing' ),
'new' => array( 'group_new' ) )
) ) );
$form->add( new \IPS\Helpers\Form\Text( 'template_group_new', NULL, FALSE, array( 'regex' => '/^([a-z0-9_]+?)?$/' ), NULL, NULL, NULL, 'group_new' ) );
$form->add( new \IPS\Helpers\Form\Select( 'template_group_existing', NULL, FALSE, array( 'options' => $groups ), NULL, NULL, NULL, 'group_existing' ) );
}
if ( ! \IPS\Request::i()->isAjax() AND $type !== 'database' )
{
$form->add( new \IPS\Helpers\Form\TextArea( 'template_content', NULL ) );
}
if ( $values = $form->values() )
{
$type = \IPS\Request::i()->type;
if ( $type == 'database' )
{
/* We need to copy templates */
$group = \IPS\cms\Databases::$templateGroups[ $values['database_template_type' ] ];
$templates = iterator_to_array( \IPS\Db::i()->select( '*', 'cms_templates', array( 'template_location=? AND template_group=? AND template_user_edited=0 AND template_user_created=0', 'database', $group ) ) );
foreach( $templates as $template )
{
unset( $template['template_id'] );
$template['template_original_group'] = $template['template_group'];
$template['template_group'] = str_replace( '-', '_', \IPS\Http\Url::seoTitle( $values['template_title'] ) );
$save = array();
foreach( $template as $k => $v )
{
$k = \mb_substr( $k, 9 );
$save[ $k ] = $v;
}
/* Make sure template tags call the correct group */
if ( mb_stristr( $save['content'], '{template' ) )
{
preg_match_all( '/\{([a-z]+?=([\'"]).+?\\2 ?+)}/', $save['content'], $matches, PREG_SET_ORDER );
/* Work out the plugin and the values to pass */
foreach( $matches as $index => $array )
{
preg_match_all( '/(.+?)=' . $array[ 2 ] . '(.+?)' . $array[ 2 ] . '\s?/', $array[ 1 ], $submatches );
$plugin = array_shift( $submatches[ 1 ] );
if ( $plugin == 'template' )
{
$value = array_shift( $submatches[ 2 ] );
$options = array();
foreach ( $submatches[ 1 ] as $k => $v )
{
$options[ $v ] = $submatches[ 2 ][ $k ];
}
if ( isset( $options['app'] ) and $options['app'] == 'cms' and isset( $options['location'] ) and $options['location'] == 'database' and isset( $options['group'] ) and $options['group'] == $template['template_original_group'] )
{
$options['group'] = $template['template_group'];
$replace = '{template="' . $value . '" app="' . $options['app'] . '" location="' . $options['location'] . '" group="' . $options['group'] . '" params="' . ( isset($options['params']) ? $options['params'] : NULL ) . '"}';
$save['content'] = str_replace( $matches[$index][0], $replace, $save['content'] );
}
}
}
}
$newTemplate = \IPS\cms\Templates::add( $save );
}
if ( $values['database_assign_to'] )
{
try
{
$db = \IPS\cms\Databases::load( $values['database_assign_to'] );
$key = 'template_' . $values['database_template_type'];
$db->$key = $template['template_group'];
$db->save();
}
catch( \OutOfRangeException $ex ) { }
}
}
else if ( $type === 'block' )
{
$save = array(
'title' => str_replace( '-', '_', \IPS\Http\Url::seoTitle( $values['template_title'] ) ),
'params' => isset( $values['template_params'] ) ? $values['template_params'] : null,
'location' => $type
);
/* Get template */
list( $widgetApp, $widgetKey ) = explode( '__', $values['block_template_plugin_import'] );
/* Find it from the normal template system */
$plugin = \IPS\Widget::load( \IPS\Application::load( $widgetApp ), $widgetKey, uniqid(), array() );
$location = $plugin->getTemplateLocation();
$theme = ( \IPS\IN_DEV ) ? \IPS\Theme::master() : $values['block_template_theme_import'];
$templateBits = $theme->getRawTemplates( $location['app'], $location['location'], $location['group'], \IPS\Theme::RETURN_ALL );
$templateBit = $templateBits[ $location['app'] ][ $location['location'] ][ $location['group'] ][ $location['name'] ];
$save['content'] = $templateBit['template_content'];
$save['params'] = $templateBit['template_data'];
$save['group'] = $widgetKey;
$newTemplate = \IPS\cms\Templates::add( $save );
}
else
{
$save = array( 'title' => $values['template_title'] );
/* Page, css, js */
if ( $type == 'js' or $type == 'css' )
{
$fileExt = ( $type == 'js' ) ? '.js' : ( $type == 'css' ? '.css' : NULL );
if ( $fileExt AND ! preg_match( '#' . preg_quote( $fileExt, '#' ) . '$#', $values['template_title'] ) )
{
$values['template_title'] .= $fileExt;
}
$save['title'] = $values['template_title'];
$save['type'] = $type;
}
if ( $type === 'page' AND $values['theme_template_group_type'] == 'existing' AND $values['template_group_existing'] == 'custom_wrappers' )
{
$save['params'] = '$html=NULL, $title=NULL';
}
if ( $type === 'page' AND $values['theme_template_group_type'] == 'existing' AND $values['template_group_existing'] == 'page_builder' )
{
$save['params'] = '$page, $widgets';
}
$save['group'] = ( $values['theme_template_group_type'] == 'existing' ) ? $values['template_group_existing'] : $values['template_group_new'];
if ( isset( $values['template_content'] ) )
{
$save['content'] = $values['template_content'];
}
$save['location'] = $type;
$newTemplate = \IPS\cms\Templates::add( $save );
}
/* Done */
if( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->json( array(
'id' => $newTemplate->id,
'title' => $newTemplate->title,
'params' => $newTemplate->params,
'desc' => $newTemplate->description,
'container' => $newTemplate->container,
'location' => $newTemplate->location
) );
}
else
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=cms&module=pages&controller=templates' ), 'saved' );
}
}
/* Display */
$title = \strip_tags( \IPS\Member::loggedIn()->language()->get( 'content_template_add_template_' . $type ) );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->block( $title, $form, FALSE );
\IPS\Output::i()->title = $title;
}
/**
* Delete a template
* This can be either a CSS template or a HTML template
*
* @return void
*/
public function delete()
{
/* Check permission */
\IPS\Dispatcher::i()->checkAcpPermission( 'template_delete' );
$key = \IPS\Request::i()->t_key;
$return = array(
'template_content' => NULL,
'template_id' => NULL
);
try
{
\IPS\cms\Templates::load( $key )->delete();
/* Now reload */
try
{
$template = \IPS\cms\Templates::load( $key );
$return['template_location'] = $template->location;
$return['template_content'] = $template->content;
$return['template_id'] = $template->id;
$return['InheritedValue'] = ( $template->user_added ) ? 'custom' : ( $template->user_edited ? 'changed' : 0 );
}
catch( \OutOfRangeException $ex )
{
}
}
catch( \OutOfRangeException $ex )
{
\IPS\Output::i()->error( 'node_error', '3S121/1', 500, '' );
}
/* Clear guest page caches */
\IPS\Data\Cache::i()->clearAll();
if( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->json( $return );
}
else
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=cms&module=pages&controller=templates' ), 'completed' );
}
}
/**
* Saves a template
*
* @return void
*/
public function save()
{
$key = \IPS\Request::i()->t_key;
$contentKey = 'editor_' . $key;
$content = \IPS\Request::i()->$contentKey;
$description = \IPS\Request::i()->t_description;
$variables = isset( \IPS\Request::i()->t_variables ) ? \IPS\Request::i()->t_variables : '';
try
{
$obj = \IPS\cms\Templates::load( $key );
$obj->location = \IPS\Request::i()->t_location;
$obj->group = empty( \IPS\Request::i()->t_group ) ? null : \IPS\Request::i()->t_group;
$obj->title = \IPS\Request::i()->t_name;
$obj->params = $variables;
$obj->content = $content;
if( $description )
{
$obj->description = $description;
}
$obj->save();
$url = array(
't_location' => $obj->location,
't_group' => $obj->group,
't_key' => $key
);
}
catch( \Exception $ex )
{
\IPS\Output::i()->json( array( 'msg' => $ex->getMessage() ) );
}
/* reload to return new item Id */
$obj = \IPS\cms\Templates::load( $key );
/* Clear guest page caches */
\IPS\Data\Cache::i()->clearAll();
if( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->json( array( 'template_id' => $obj->id, 'template_title' => $obj->title, 'template_container' => $obj->container, 'template_user_added' => $obj->user_created ) );
}
else
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=cms&module=pages&controller=templates&' . implode( '&', $url ) ), 'completed' );
}
}
}