Invision Power Services, Inc.
* @copyright (c) 2014 Invision Power Services, Inc.
* @package IPS Community Suite
* @subpackage Content
* @since 13 Jan 2014
* @version
*/
namespace IPS\cms;
spl_autoload_register( function( $class )
{
if ( mb_substr( $class, 0, 15 ) === 'IPS\cms\Records' and is_numeric( mb_substr( $class, 15, 1 ) ) )
{
$databaseId = intval( mb_substr( $class, 15 ) );
$databases = \IPS\cms\Databases::databases();
if ( ! isset( $databases[ $databaseId ] ) )
{
return false;
}
$titleField = $databases[ $databaseId ]->field_title;
$contentField = $databases[ $databaseId ]->field_content;
$titleLang = 'content_db_lang_su_' . $databaseId;
$includeInSearch = $databases[ $databaseId ]->search ? "TRUE" : "FALSE";
$data = << 'member_id',
'container' => 'category_id',
'date' => 'record_publish_date',
'is_future_entry' => 'record_future_date',
'future_date' => 'record_publish_date',
'title' => 'field_{$titleField}',
'content' => 'field_{$contentField}',
'num_comments' => 'record_comments',
'unapproved_comments' => 'record_comments_queued',
'hidden_comments' => 'record_comments_hidden',
'last_comment' => 'record_last_comment',
'last_comment_by' => 'record_last_comment_by',
'last_comment_name' => 'record_last_comment_name',
'views' => 'record_views',
'approved' => 'record_approved',
'pinned' => 'record_pinned',
'locked' => 'record_locked',
'featured' => 'record_featured',
'rating' => 'record_rating',
'rating_hits' => 'rating_hits',
'rating_average' => 'record_rating',
'rating_total' => 'rating_value',
'num_reviews' => 'record_reviews',
'last_review' => 'record_last_review',
'last_review_by' => 'record_last_review_by',
'last_review_name' => 'record_last_review_name',
'updated' => 'record_last_comment'
);
public static \$pagePath;
}
EOF;
eval( $data );
}
if ( mb_substr( $class, 0, 23 ) === 'IPS\cms\Records\Comment' and is_numeric( mb_substr( $class, 23, 1 ) ) )
{
$databaseId = intval( mb_substr( $class, 23 ) );
$data = <<checkForTable('cms_databases') )
{
return $menu;
}
/* Now add in the databases... */
foreach( \IPS\cms\Databases::acpMenu() as $database )
{
$menu['databases'][ 'records_' . $database['id'] ] = array(
'tab' => 'cms',
'controller' => 'records',
'do' => 'manage&database_id=' . $database['id'],
'restriction' => 'records_manage'
);
if ( $database['use_categories'] )
{
$menu['databases'][ 'categories_' . $database['id'] ] = array(
'tab' => 'cms',
'controller' => 'categories',
'do' => 'manage&database_id=' . $database['id'],
'restriction' => 'categories_manage'
);
}
$menu['databases'][ 'fields_' . $database['id'] ] = array(
'tab' => 'cms',
'controller' => 'fields',
'do' => 'manage&database_id=' . $database['id'],
'restriction' => 'cms_fields_manage'
);
\IPS\Member::loggedIn()->language()->words[ 'menu__cms_databases_records_' . $database['id'] ] = \IPS\Member::loggedIn()->language()->addToStack('content_db_' . $database['id']);
\IPS\Member::loggedIn()->language()->words[ 'menu__cms_databases_categories_' . $database['id'] ] = ' ' . \IPS\Member::loggedIn()->language()->addToStack('menu__cms_categories');
\IPS\Member::loggedIn()->language()->words[ 'menu__cms_databases_fields_' . $database['id'] ] = ' ' . \IPS\Member::loggedIn()->language()->addToStack('menu__cms_fields');
}
return $menu;
}
/**
* Get Extensions
*
* @param \IPS\Application|string $app The app key of the application which owns the extension
* @param string $extension Extension Type
* @param bool $construct Should an object be returned? (If false, just the classname will be returned)
* @param \IPS\Member|bool $checkAccess Check access permission for extension against supplied member (or logged in member, if TRUE)
* @return array
*/
public function extensions( $app, $extension, $construct=TRUE, $checkAccess=FALSE )
{
$classes = parent::extensions( $app, $extension, $construct, $checkAccess );
if ( $extension === 'EditorLocations' )
{
foreach( \IPS\cms\Databases::databases() as $obj )
{
$classname = '\\IPS\\cms\\extensions\\core\\EditorLocations\\Records' . $obj->_id;
if ( method_exists( $classname, 'generate' ) )
{
$classes = array_merge( $classes, $classname::generate() );
}
elseif ( !$construct )
{
$classes[ 'Records' . $obj->_id ] = $classname;
}
else
{
try
{
$classes[ 'Records' . $obj->_id ] = new $classname( $checkAccess === TRUE ? \IPS\Member::loggedIn() : ( $checkAccess === FALSE ? NULL : $checkAccess ) );
}
catch( \RuntimeException $e ){}
}
}
}
return $classes;
}
/**
* Developer sync items
*
* @param int $lastSync Last time syncd
* @return boolean Updated (true), nothing updated(false)
*/
public function developerSync( $lastSync )
{
$updated = false;
if ( $lastSync < filemtime( \IPS\ROOT_PATH . "/applications/{$this->directory}/data/databaseschema.json" ) )
{
foreach( \IPS\cms\Databases::databases() as $key => $db )
{
\IPS\cms\Databases::checkandFixDatabaseSchema( $db->_id );
$updated = TRUE;
}
}
return $updated;
}
/**
* Install 'other' items.
*
* @return void
*/
public function installOther()
{
/* Install default database and page */
$database = new \IPS\cms\Databases;
$database->key = 'articles';
$database->save();
/* Add in permissions */
$groups = array();
foreach( \IPS\Db::i()->select( 'g_id', 'core_groups', array( 'g_access_cp=1' ) ) as $row )
{
$groups[] = $row;
}
$default = implode( ',', $groups );
\IPS\Db::i()->insert( 'core_permission_index', array(
'app' => 'cms',
'perm_type' => 'databases',
'perm_type_id' => $database->id,
'perm_view' => '*', # view
'perm_2' => '*', # read
'perm_3' => $default, # add
'perm_4' => $default, # edit
'perm_5' => $default, # reply
'perm_6' => $default # rate
) );
/* Needs to be added before createDatabase is called */
\IPS\Lang::saveCustom( 'cms', "content_db_" . $database->id, "Статьи" );
\IPS\Lang::saveCustom( 'cms', "module__cms_records" . $database->id, "Статьи" );
\IPS\Lang::saveCustom( 'cms', "content_db_" . $database->id . '_desc', "Статьи нашего сайта" );
\IPS\Lang::saveCustom( 'cms', "content_db_lang_sl_" . $database->id, 'статья' );
\IPS\Lang::saveCustom( 'cms', "content_db_lang_pl_" . $database->id, 'статьи' );
\IPS\Lang::saveCustom( 'cms', "content_db_lang_su_" . $database->id, 'Статья' );
\IPS\Lang::saveCustom( 'cms', "content_db_lang_pu_" . $database->id, 'Статьи' );
\IPS\Lang::saveCustom( 'cms', "content_db_lang_ia_" . $database->id, 'статья' );
\IPS\Lang::saveCustom( 'cms', "content_db_lang_sl_" . $database->id . '_pl', 'Статьи' );
\IPS\Lang::saveCustom( 'cms', "cms_create_menu_records_" . $database->id, 'Запись в Статьи' );
\IPS\Lang::saveCustom( 'cms', "digest_area_records" . $database->id, "Статьи" );
\IPS\Lang::saveCustom( 'cms', "cms_records" . $database->id . '_pl', 'Статья' );
try
{
\IPS\cms\Databases::createDatabase( $database );
}
catch ( \Exception $ex )
{
$database->delete();
\IPS\Log::log( $ex, 'pages_create_db_error' );
throw new \LogicException( $ex->getMessage() );
}
$database->all_editable = 0;
$database->revisions = 1;
$database->search = 1;
$database->comment_bump = 1; # Just new comments bump record
$database->rss = 10;
$database->record_count = 1;
$database->fixed_field_perms = array( 'record_image' => array( 'visible' => true, 'perm_view' => '*', 'perm_2' => '*', 'perm_3' => '*' ) );
$database->options['comments'] = 1;
$database->field_sort = 'primary_id_field';
$database->field_direction = 'asc';
$database->field_perpage = 25;
$database->save();
/* Create default record */
$item = 'IPS\cms\Records' . $database->id;
$comment = 'IPS\cms\Records\Comment' . $database->id;
$container = 'IPS\cms\Categories' . $database->id;
$link = (string) \IPS\Http\Url::ips('docs/pages_docs');
$content = <<Добро пожаловать в приложение Страницы!
Приложение Страницы призвано расширить ваш сайт путём гибкого управления контентом, разработанное специально для сообществ.
Создайте совершенно новые разделы вашего сообщества, используя такие особенности, как блоки, базы данных и статьи, и внедряя дополнительную информацию из других разделов сообщества.
Создавайте собственные страницы, используя наш удобный WYSIWYG редактор.
Создавайте блоки, которые отображают все виды информации из всего вашего сообщества для создания динамических страниц, или используйте стандартные готовые блоки, присутствующие в IPS Community Suite.
Просмотреть документацию приложения
EOF;
$titleField = 'field_' . $database->field_title;
$contentField = 'field_' . $database->field_content;
$category = $container::load( $database->_default_category );
$member = \IPS\Member::loggedIn()->member_id ? \IPS\Member::loggedIn() : \IPS\Member::load(1);
$record = $item::createItem( $member, \IPS\Request::i()->ipAddress(), \IPS\DateTime::ts( time() ), $category, FALSE );
$record->$titleField = "Добро пожаловать в Страницы";
$record->$contentField = $content;
$record->save();
\IPS\Content\Search\Index::i()->index( $record );
$category->last_record_date = time();
$category->save();
/* Create the page */
$pageValues = array(
'page_name' => "Статьи",
'page_title' => "Статьи",
'page_seo_name' => "articles.html",
'page_folder_id' => 0,
'page_ipb_wrapper' => 1,
'page_show_sidebar' => 1,
'page_type' => 'builder',
'page_template' => 'page_builder__single_column__page_page_builder_single_column'
);
try
{
$page = \IPS\cms\Pages\Page::createFromForm( $pageValues, 'html' );
}
catch( \Exception $ex )
{
\IPS\Log::log( $ex, 'pages_create_page_error' );
}
$page->setAsDefault();
\IPS\Db::i()->replace( 'core_permission_index', array(
'app' => 'cms',
'perm_type' => 'pages',
'perm_type_id' => $page->id,
'perm_view' => '*'
) );
$database->page_id = $page->id;
$database->save();
unset( \IPS\Data\Store::i()->pages_page_urls );
$defaultWidgets = array();
$buttonUrl = (string) \IPS\Http\Url::internal( 'applications/cms/interface/default/block_arrow.png', 'none' );
$defaultContent = <<
Добро пожаловать в приложение Страницы!
Для начала, убедитесь, что вы авторизовались и нажмите на стрелку с правой стороны
, чтобы развернуть менеджер блоков.
Вы можете перемещать, добавлять и редактировать блоки без необходимости программирования!
EOF;
/* Default WYSIWYG widget */
$defaultWidgets[] = array(
'app' => 'cms',
'key' => 'Wysiwyg',
'unique' => uniqid(),
'configuration' => array( 'content' => $defaultContent )
);
/* Default database widget */
$defaultWidgets[] = array(
'app' => 'cms',
'key' => 'Database',
'unique' => uniqid(),
'configuration' => array( 'database' => $database->id )
);
\IPS\Db::i()->insert( 'cms_page_widget_areas', array(
'area_page_id' => $page->id,
'area_widgets' => json_encode( $defaultWidgets ),
'area_area' => 'col1',
'area_orientation' => 'horizontal'
) );
/* Add block container (custom)*/
$container = new \IPS\cms\Blocks\Container;
$container->parent_id = 0;
$container->name = "Дополнительно";
$container->type = 'block';
$container->key = 'block_custom';
$container->save();
/* Add block container (plugins) */
$container = new \IPS\cms\Blocks\Container;
$container->parent_id = 0;
$container->name = "Плагины";
$container->type = 'block';
$container->key = 'block_plugins';
$container->save();
\IPS\cms\Templates::importXml( \IPS\ROOT_PATH . "/applications/cms/data/cms_theme.xml", NULL, NULL, FALSE );
}
/**
* Install the application's templates
* Theme resources should be raw binary data everywhere (filesystem and DB) except in the theme XML download where they are base64 encoded.
*
* @param bool $update If set to true, do not overwrite current theme setting values
* @param int|null $offset Offset to begin import from
* @param int|null $limit Number of rows to import
* @return int Rows inserted
*/
public function installTemplates( $update=FALSE, $offset=null, $limit=null )
{
$inserted = parent::installTemplates( $update, $offset, $limit );
if ( ( ! $inserted or ( $inserted < $limit ) ) AND $update )
{
\IPS\cms\Templates::importXml( \IPS\ROOT_PATH . "/applications/cms/data/cms_theme.xml", NULL, NULL, $update );
}
}
/**
* Build skin templates for an app
*
* @return void
* @throws \RuntimeException
*/
public function buildThemeTemplates()
{
parent::buildThemeTemplates();
foreach( array( 'database', 'block', 'page' ) as $location )
{
\IPS\cms\Theme::importInDev( $location );
}
/* Build XML and write to app directory */
$xml = new \XMLWriter;
$xml->openMemory();
$xml->setIndent( TRUE );
$xml->startDocument( '1.0', 'UTF-8' );
/* Root tag */
$xml->startElement('theme');
$xml->startAttribute('name');
$xml->text( "Default" );
$xml->endAttribute();
$xml->startAttribute('author_name');
$xml->text( "Invision Power Services, Inc" );
$xml->endAttribute();
$xml->startAttribute('author_url');
$xml->text( "http://www.invisionpower.com" );
$xml->endAttribute();
/* Templates */
foreach ( \IPS\Db::i()->select( '*', 'cms_templates', array( 'template_master=1 and template_user_created=0 and template_user_edited=0' ), 'template_group, template_title' ) as $template )
{
/* Initiate the tag */
$xml->startElement('template');
foreach( $template as $k => $v )
{
if ( in_array( \substr( $k, 9 ), array('key', 'title', 'desc', 'location', 'group', 'params', 'app', 'type' ) ) )
{
$xml->startAttribute( $k );
$xml->text( $v );
$xml->endAttribute();
}
}
/* Write value */
if ( preg_match( '/<|>|&/', $template['template_content'] ) )
{
$xml->writeCData( str_replace( ']]>', ']]]]>', $template['template_content'] ) );
}
else
{
$xml->text( $template['template_content'] );
}
/* Close the tag */
$xml->endElement();
}
/* Finish */
$xml->endDocument();
/* Write it */
if ( is_writable( \IPS\ROOT_PATH . '/applications/' . $this->directory . '/data' ) )
{
\file_put_contents( \IPS\ROOT_PATH . '/applications/' . $this->directory . '/data/cms_theme.xml', $xml->outputMemory() );
}
else
{
throw new \RuntimeException( \IPS\Member::loggedIn()->language()->addToStack('dev_could_not_write_data') );
}
}
/**
* [Node] Get Icon for tree
*
* @note Return the class for the icon (e.g. 'globe')
* @return string|null
*/
protected function get__icon()
{
return 'folder-open';
}
/**
* Default front navigation
*
* @code
// Each item...
array(
'key' => 'Example', // The extension key
'app' => 'core', // [Optional] The extension application. If ommitted, uses this application
'config' => array(...), // [Optional] The configuration for the menu item
'title' => 'SomeLangKey', // [Optional] If provided, the value of this language key will be copied to menu_item_X
'children' => array(...), // [Optional] Array of child menu items for this item. Each has the same format.
)
return array(
'rootTabs' => array(), // These go in the top row
'browseTabs' => array(), // These go under the Browse tab on a new install or when restoring the default configuraiton; or in the top row if installing the app later (when the Browse tab may not exist)
'browseTabsEnd' => array(), // These go under the Browse tab after all other items on a new install or when restoring the default configuraiton; or in the top row if installing the app later (when the Browse tab may not exist)
'activityTabs' => array(), // These go under the Activity tab on a new install or when restoring the default configuraiton; or in the top row if installing the app later (when the Activity tab may not exist)
)
* @endcode
* @return array
*/
public function defaultFrontNavigation()
{
$browseTabs = array();
try
{
$defaultPage = \IPS\cms\Pages\Page::getDefaultPage();
$browseTabs[] = array( 'key' => 'Pages', 'config' => array( 'menu_content_page' => $defaultPage->id, 'menu_title_page_type' => 0 ) );
}
catch( \OutOfRangeException $ex ) { }
return array(
'rootTabs' => array(),
'browseTabs' => $browseTabs,
'browseTabsEnd' => array(),
'activityTabs' => array()
);
}
}