Index: branches/RC/core/units/categories/categories_config.php =================================================================== --- branches/RC/core/units/categories/categories_config.php (revision 11896) +++ branches/RC/core/units/categories/categories_config.php (revision 11897) @@ -1,403 +1,403 @@ <?php /** * @version $Id$ * @package In-Portal * @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved. * @license GNU/GPL * In-Portal is Open Source software. * This means that this software may have been modified pursuant * the GNU General Public License, and as distributed it includes * or is derivative of works licensed under the GNU General Public License * or other free or open source software licenses. * See http://www.in-portal.net/license/ for copyright notices and details. */ $config = Array ( 'Prefix' => 'c', 'ItemClass' => Array ('class' => 'CategoriesItem', 'file' => 'categories_item.php', 'build_event' => 'OnItemBuild'), 'ListClass' => Array ('class' => 'kDBList', 'file' => '', 'build_event' => 'OnListBuild'), 'EventHandlerClass' => Array ('class' => 'CategoriesEventHandler', 'file' => 'categories_event_handler.php', 'build_event' => 'OnBuild'), 'TagProcessorClass' => Array ('class' => 'CategoriesTagProcessor', 'file' => 'categories_tag_processor.php', 'build_event' => 'OnBuild'), 'RegisterClasses' => Array ( Array ('pseudo' => 'kPermCacheUpdater', 'class' => 'kPermCacheUpdater', 'file' => 'cache_updater.php', 'build_event' => ''), ), 'ConfigPriority' => 0, 'Hooks' => Array ( Array ( 'Mode' => hAFTER, 'Conditional' => false, 'HookToPrefix' => 'adm', //self 'HookToSpecial' => '*', 'HookToEvent' => Array('OnRebuildThemes'), 'DoPrefix' => '', 'DoSpecial' => '', 'DoEvent' => 'OnAfterRebuildThemes', ), Array ( 'Mode' => hBEFORE, 'Conditional' => false, 'HookToPrefix' => '', 'HookToSpecial' => '*', 'HookToEvent' => Array('OnAfterConfigRead'), 'DoPrefix' => 'cdata', 'DoSpecial' => '*', 'DoEvent' => 'OnDefineCustomFields', ), ), 'AutoLoad' => true, 'CatalogItem' => true, 'AdminTemplatePath' => 'categories', 'AdminTemplatePrefix' => 'categories_', 'QueryString' => Array ( 1 => 'id', 2 => 'Page', 3 => 'event', 4 => 'mode', ), 'AggregateTags' => Array ( Array ( 'AggregateTo' => 'm', 'AggregatedTagName' => 'CategoryLink', 'LocalTagName' => 'CategoryLink', ), ), 'IDField' => 'CategoryId', 'StatusField' => Array ('IsMenu'), // 'Status' 'TitleField' => 'Name', 'TitlePhrase' => 'la_Text_Category', 'ItemType' => 1, // used for custom fields only 'StatisticsInfo' => Array ( 'pending' => Array ( 'icon' => 'icon16_cat_pending.gif', 'label' => 'la_tab_Categories', 'js_url' => '#url#', 'url' => Array('t' => 'catalog/advanced_view', 'SetTab' => 'c', 'pass' => 'm,c.showall', 'c.showall_event' => 'OnSetFilterPattern', 'c.showall_filters' => 'show_active=0,show_pending=1,show_disabled=0,show_new=1,show_pick=1'), 'status' => STATUS_PENDING, ), ), 'TableName' => TABLE_PREFIX.'Category', 'ViewMenuPhrase' => 'la_text_Categories', 'CatalogTabIcon' => 'icon16_folder.gif', 'TitlePresets' => Array ( 'default' => Array ( 'new_status_labels' => Array ('c' => '!la_title_Adding_Category!'), 'edit_status_labels' => Array ('c' => '!la_title_Editing_Category!'), 'new_titlefield' => Array ('c' => '!la_title_New_Category!'), ), 'category_list' => Array ('prefixes' => Array ('c_List'), 'format' => "!la_title_Categories! (#c_recordcount#)"), 'catalog' => Array ( 'prefixes' => Array (), 'format' => "<span id='category_path'>!la_title_Categories!</span>", 'toolbar_buttons' => Array ('select', 'cancel', 'upcat', 'homecat', 'new_cat', 'new_link', 'new_article', 'new_topic', 'new_item', 'edit', 'delete', 'approve', 'decline', 'cut', 'copy', 'paste', 'move_up', 'move_down', 'rebuild_cache', 'view') ), 'advanced_view' => Array ( 'prefixes' => Array (), 'format' => "!la_title_AdvancedView!", 'toolbar_buttons' => Array ('select', 'cancel', 'new_cat', 'new_link', 'new_article', 'new_topic', 'new_item', 'edit', 'delete', 'approve', 'decline', 'view'), ), 'reviews' => Array ('prefixes' => Array (), 'format' => "!la_title_Reviews!"), 'review_edit' => Array ('prefixes' => Array (), 'format' => "!la_title_Editing_Review!"), 'categories_edit' => Array ('prefixes' => Array ('c'), 'format' => "#c_status# '#c_titlefield#' - !la_title_General!"), 'categories_properties' => Array ('prefixes' => Array ('c'), 'format' => "#c_status# '#c_titlefield#' - !la_title_Properties!"), 'categories_relations' => Array ('prefixes' => Array ('c'), 'format' => "#c_status# '#c_titlefield#' - !la_title_Relations!"), 'categories_related_searches' => Array ( 'prefixes' => Array ('c'), 'format' => "#c_status# '#c_titlefield#' - !la_title_RelatedSearches!", 'toolbar_buttons' => Array ('new_related_search', 'edit', 'delete', 'move_up', 'move_down', 'approve', 'decline', 'view'), ), 'categories_images' => Array ('prefixes' => Array ('c'), 'format' => "#c_status# '#c_titlefield#' - !la_title_Images!"), 'categories_permissions' => Array ('prefixes' => Array ('c', 'g_List'), 'format' => "#c_status# '#c_titlefield#' - !la_title_Permissions!"), 'categories_custom' => Array ('prefixes' => Array ('c'), 'format' => "#c_status# '#c_titlefield#' - !la_title_Custom!"), 'categories_update' => Array ('prefixes' => Array (), 'format' => "!la_title_UpdatingCategories!"), 'images_edit' => Array ( 'prefixes' => Array ('c', 'c-img'), 'new_status_labels' => Array ('c-img' => '!la_title_Adding_Image!'), 'edit_status_labels' => Array ('c-img' => '!la_title_Editing_Image!'), 'new_titlefield' => Array ('c-img' => ''), 'format' => "#c_status# '#c_titlefield#' - #c-img_status# '#c-img_titlefield#'", ), 'relations_edit' => Array ( 'prefixes' => Array ('c', 'c-rel'), 'new_status_labels' => Array ('c-rel' => "!la_title_Adding_Relationship! '!la_title_New_Relationship!'"), 'edit_status_labels' => Array ('c-rel' => '!la_title_Editing_Relationship!'), 'format' => "#c_status# '#c_titlefield#' - #c-rel_status#", ), 'related_searches_edit' => Array ( 'prefixes' => Array ('c', 'c-search'), 'new_status_labels' => Array ('c-search' => "!la_title_Adding_RelatedSearch_Keyword!"), 'edit_status_labels' => Array ('c-search' => '!la_title_Editing_RelatedSearch_Keyword!'), 'format' => "#c_status# '#c_titlefield#' - #c-search_status#", ), 'edit_content' => Array ('format' => '!la_EditingContent!'), 'tree_site' => Array ('format' => '!la_selecting_categories!'), ), 'EditTabPresets' => Array ( 'Default' => Array ( 'general' => Array ('title' => 'la_tab_General', 't' => 'categories/categories_edit', 'priority' => 1), 'properties' => Array ('title' => 'la_tab_Properties', 't' => 'categories/categories_edit_properties', 'priority' => 2), 'relations' => Array ('title' => 'la_tab_Relations', 't' => 'categories/categories_edit_relations', 'priority' => 3), 'related_searches' => Array ('title' => 'la_tab_Related_Searches', 't' => 'categories/categories_edit_related_searches', 'priority' => 4), 'images' => Array ('title' => 'la_tab_Images', 't' => 'categories/categories_edit_images', 'priority' => 5), 'permissions' => Array ('title' => 'la_tab_Permissions', 't' => 'categories/categories_edit_permissions', 'priority' => 6), 'custom' => Array ('title' => 'la_tab_Custom', 't' => 'categories/categories_edit_custom', 'priority' => 7), ), ), 'PermItemPrefix' => 'CATEGORY', 'PermSection' => Array ('main' => 'CATEGORY:in-portal:categories', /*'search' => 'in-portal:configuration_search',*/ 'email' => 'in-portal:configuration_email', 'custom' => 'in-portal:configuration_custom'), 'Sections' => Array ( 'in-portal:configure_categories' => Array ( 'parent' => 'in-portal:website_setting_folder', 'icon' => 'settings_output', 'label' => 'la_tab_ConfigOutput', 'url' => Array ('t' => 'config/config_universal', 'pass_section' => true, 'pass' => 'm'), 'permissions' => Array ('view', 'edit'), 'priority' => 11.1, 'type' => stTREE, ), 'in-portal:configuration_search' => Array ( 'parent' => 'in-portal:website_setting_folder', 'icon' => 'settings_search', 'label' => 'la_tab_ConfigSearch', 'url' => Array ('t' => 'config/config_search', 'module_key' => 'category', 'pass_section' => true, 'pass' => 'm'), 'permissions' => Array ('view', 'edit'), 'priority' => 11.2, 'type' => stTREE, ), 'in-portal:configuration_email' => Array ( 'parent' => 'in-portal:website_setting_folder', 'icon' => 'settings_email', 'label' => 'la_tab_ConfigE-mail', 'url' => Array ('t' => 'config/config_email', 'module' => 'Core:Category', 'pass_section' => true, 'pass' => 'm'), 'permissions' => Array ('view', 'edit'), 'priority' => 11.3, 'type' => stTREE, ), 'in-portal:configuration_custom' => Array ( 'parent' => 'in-portal:website_setting_folder', 'icon' => 'settings_custom', 'label' => 'la_tab_ConfigCustom', 'url' => Array ('t' => 'custom_fields/custom_fields_list', 'cf_type' => 1, 'pass_section' => true, 'pass' => 'm,cf'), 'permissions' => Array ('view', 'add', 'edit', 'delete'), 'priority' => 11.4, 'type' => stTREE, ), ), 'FilterMenu' => Array ( 'Groups' => Array ( Array ('mode' => 'AND', 'filters' => Array ('show_active', 'show_pending', 'show_disabled'), 'type' => WHERE_FILTER), Array ('mode' => 'AND', 'filters' => Array ('show_new'), 'type' => HAVING_FILTER), Array ('mode' => 'AND', 'filters' => Array ('show_pick'), 'type' => WHERE_FILTER), ), 'Filters' => Array ( 'show_active' => Array ('label' =>'la_Active', 'on_sql' => '', 'off_sql' => 'Status != 1'), 'show_pending' => Array ('label' => 'la_Pending', 'on_sql' => '', 'off_sql' => 'Status != 2'), 'show_disabled' => Array ('label' => 'la_Disabled', 'on_sql' => '', 'off_sql' => 'Status != 0'), 's1' => Array (), 'show_new' => Array ('label' => 'la_Text_New', 'on_sql' => '', 'off_sql' => '`IsNew` != 1'), 'show_pick' => Array ('label' => 'la_prompt_EditorsPick', 'on_sql' => '', 'off_sql' => '`EditorsPick` != 1'), ) ), 'ListSQLs' => Array ( '' => ' SELECT %1$s.* %2$s FROM %1$s LEFT JOIN '.TABLE_PREFIX.'Images img ON img.ResourceId = %1$s.ResourceId AND img.DefaultImg = 1 LEFT JOIN '.TABLE_PREFIX.'PermCache ON '.TABLE_PREFIX.'PermCache.CategoryId = %1$s.CategoryId LEFT JOIN '.TABLE_PREFIX.'%3$sCategoryCustomData cust ON %1$s.ResourceId = cust.ResourceId' ), 'SubItems' => Array ('c-rel', 'c-search','c-img', 'c-cdata', 'c-perm', 'content'), 'ListSortings' => Array ( '' => Array ( 'Sorting' => Array ('Priority' => 'desc', 'Name' => 'asc'), ) ), 'CalculatedFields' => Array ( '' => Array ( 'CurrentSort' => "REPLACE(ParentPath, CONCAT('|', ".'%1$s'.".CategoryId, '|'), '')", 'SameImages' => 'img.SameImages', 'LocalThumb' => 'img.LocalThumb', 'ThumbPath' => 'img.ThumbPath', 'ThumbUrl' => 'img.ThumbUrl', 'LocalImage' => 'img.LocalImage', 'LocalPath' => 'img.LocalPath', 'FullUrl' => 'img.Url', ) ), 'CacheModRewrite' => true, 'Fields' => Array ( 'CategoryId' => Array ('type' => 'int', 'not_null' => 1,'default' => 0), 'Type' => Array ('type' => 'int', 'not_null' => 1,'default' => 0), 'SymLinkCategoryId' => Array ('type' => 'int', 'default' => NULL), 'ParentId' => Array ('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (), 'not_null' => 1,'default' => 0, 'required' => 1), - 'Name' => Array ('type' => 'string', 'formatter' => 'kMultiLanguage', 'format'=>'no_default', 'not_null' => 1, 'required' => 1, 'default' => ''), + 'Name' => Array ('type' => 'string', 'formatter' => 'kMultiLanguage', 'not_null' => 1, 'required' => 1, 'default' => ''), 'Filename' => Array ('type' => 'string', 'not_null' => 1, 'default' => ''), 'AutomaticFilename' => Array ('type' => 'int', 'not_null' => 1, 'default' => 1), - 'Description' => Array ('type' => 'string', 'formatter' => 'kMultiLanguage', 'format' => 'no_default', 'using_fck' => 1, 'default' => null), + 'Description' => Array ('type' => 'string', 'formatter' => 'kMultiLanguage', 'using_fck' => 1, 'default' => null), 'CreatedOn' => Array ('type' => 'int', 'formatter' => 'kDateFormatter', 'default'=>'#NOW#', 'required' => 1, 'not_null' => 1), 'EditorsPick' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), 'Status' => Array ('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_Active', 2 => 'la_Pending', 0 => 'la_Disabled' ), 'use_phrases' => 1, 'not_null' => 1,'default' => 1), 'Priority' => Array ('type' => 'int', 'not_null' => 1, 'formatter' => 'kOptionsFormatter', 'options' => Array (), 'default' => 0), 'MetaKeywords' => Array ('type' => 'string', 'formatter' => 'kFormatter', 'using_fck' => 1, 'default' => null), 'CachedDescendantCatsQty' => Array ('type' => 'int', 'default' => 0), 'CachedNavbar' => Array ('type' => 'string', 'formatter' => 'kMultiLanguage', 'default' => null), 'CreatedById' => Array ('type' => 'int', 'formatter' => 'kLEFTFormatter', 'error_msgs' => Array ('invalid_option' => '!la_error_UserNotFound!'), 'options' => Array (-1 => 'root', -2 => 'Guest'),'left_sql'=>'SELECT %s FROM '.TABLE_PREFIX.'PortalUser WHERE `%s` = \'%s\'', 'left_key_field' => 'PortalUserId', 'left_title_field' => 'Login', 'not_null' => 1,'default' => 0), 'ResourceId' => Array ('type' => 'int', 'default' => null), 'ParentPath' => Array ('type' => 'string', 'default' => null), 'TreeLeft' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), 'TreeRight' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), 'NamedParentPath' => Array ('type' => 'string', 'default' => null), 'MetaDescription' => Array ('type' => 'string', 'formatter' => 'kFormatter', 'using_fck' => 1, 'default' => null), 'HotItem' => Array ('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (2 => 'la_Auto', 1 => 'la_Always', 0 => 'la_Never'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 2), 'NewItem' => Array ('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (2 => 'la_Auto', 1 => 'la_Always', 0 => 'la_Never'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 2), 'PopItem' => Array ('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (2 => 'la_Auto', 1 => 'la_Always', 0 => 'la_Never'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 2), 'Modified' => Array ('type' => 'int', 'formatter' => 'kDateFormatter', 'not_null' => 1,'default' => '#NOW#'), 'ModifiedById' => Array ('type' => 'int', 'formatter' => 'kLEFTFormatter', 'error_msgs' => Array ('invalid_option' => '!la_error_UserNotFound!'), 'options' => Array (-1 => 'root', -2 => 'Guest'),'left_sql'=>'SELECT %s FROM '.TABLE_PREFIX.'PortalUser WHERE `%s` = \'%s\'', 'left_key_field' => 'PortalUserId', 'left_title_field' => 'Login', 'not_null' => 1,'default' => 0), 'CachedTemplate' => Array ('type' => 'string', 'not_null' => 1, 'default' => ''), // fields from Pages 'Template' => Array ( 'type' => 'string', 'formatter' => 'kOptionsFormatter', 'options_sql' => ' SELECT CONCAT(tf.Description, " (", TRIM(TRAILING ".des" FROM TRIM(TRAILING ".tpl" FROM FileName) ), ")") AS Title, CONCAT(FilePath, "/", TRIM(TRAILING ".tpl" FROM FileName)) AS Value FROM ' . TABLE_PREFIX . 'ThemeFiles AS tf LEFT JOIN ' . TABLE_PREFIX . 'Theme AS t ON t.ThemeId = tf.ThemeId WHERE (t.Enabled = 1) AND (tf.FileName NOT LIKE "%%.elm.tpl") AND (tf.FileName NOT LIKE "%%.des.tpl") AND (tf.FilePath = "/designs") ORDER BY tf.Description ASC, tf.FileName ASC', 'option_key_field' => 'Value', 'option_title_field' => 'Title', /*'required' => 1,*/ 'default' => null ), 'UseExternalUrl' => Array ( 'type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (0 => 'la_No', 1 => 'la_Yes'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 0 ), 'ExternalUrl' => Array ('type' => 'string', 'max_len' => 255, 'not_null' => 1, 'default' => ''), 'UseMenuIconUrl' => Array ( 'type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (0 => 'la_No', 1 => 'la_Yes'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 0 ), 'MenuIconUrl' => Array ('type' => 'string', 'max_len' => 255, 'not_null' => 1, 'default' => ''), - 'Title' => Array ('type' => 'string', 'formatter' => 'kMultiLanguage', 'format'=>'no_default', 'default' => '', 'not_null'=>1), - 'MenuTitle' => Array ('type' => 'string', 'formatter' => 'kMultiLanguage', 'format'=>'no_default', 'not_null' => 1, 'default' => ''), + 'Title' => Array ('type' => 'string', 'formatter' => 'kMultiLanguage', 'default' => '', 'not_null'=>1), + 'MenuTitle' => Array ('type' => 'string', 'formatter' => 'kMultiLanguage', 'not_null' => 1, 'default' => ''), 'MetaTitle' => Array ('type' => 'string', 'default' => null), 'IndexTools' => Array ('type' => 'string', 'formatter' => 'kFormatter', 'using_fck' => 1, 'default' => null), 'IsIndex' => Array ( 'type' => 'int', 'not_null' => 1, 'default' => 0, 'formatter' => 'kOptionsFormatter', 'options' => Array (0 => 'la_Regular', 1 => 'la_CategoryIndex', 2 => 'la_Container'), 'use_phrases' => 1, ), 'IsMenu' => Array ('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_Show', 0 => 'la_Hide'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 1), 'IsSystem' => Array ('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_System', 0 => 'la_Regular'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 0), 'FormId' => Array ( 'type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array ('' => ''), 'options_sql' => 'SELECT Title, FormId FROM '.TABLE_PREFIX.'Forms ORDER BY Title', 'option_key_field' => 'FormId', 'option_title_field' => 'Title', 'default' => 0 ), 'FormSubmittedTemplate' => Array ('type' => 'string', 'default' => null), 'Translated' => Array ('type' => 'int', 'formatter' => 'kMultiLanguage', 'not_null' => 1, 'default' => 0, 'db_type' => 'tinyint', 'index_type' => 'int'), 'FriendlyURL' => Array ('type' => 'string', 'not_null' => 1, 'default' => ''), 'ThemeId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), ), 'VirtualFields' => Array ( 'CurrentSort' => Array('type' => 'string', 'default' => ''), 'IsNew' => Array('type' => 'int', 'default' => 0), 'OldPriority' => Array('type' => 'int', 'default' => 0), // for primary image 'SameImages' => Array('type' => 'string', 'default' => ''), 'LocalThumb' => Array('type' => 'string', 'default' => ''), 'ThumbPath' => Array('type' => 'string', 'default' => ''), 'ThumbUrl' => Array('type' => 'string', 'default' => ''), 'LocalImage' => Array('type' => 'string', 'default' => ''), 'LocalPath' => Array('type' => 'string', 'default' => ''), 'FullUrl' => Array('type' => 'string', 'default' => ''), ), 'Grids' => Array( 'Default' => Array ( 'Icons' => Array(1 => 'icon16_folder.gif', 0 => 'icon16_folder-red.gif'), 'Fields' => Array( 'CategoryId' => Array( 'title'=>'la_col_Id', 'data_block' => 'grid_checkbox_td', 'filter_block' => 'grid_range_filter', ), 'Name' => Array( 'title'=>'la_col_PageTitle', 'data_block' => 'page_browse_td', 'filter_block' => 'grid_like_filter'), 'Modified' => Array( 'title'=>'la_col_Modified', 'filter_block' => 'grid_date_range_filter' ), 'Template' => Array( 'title'=>'la_col_TemplateType', 'filter_block' => 'grid_options_filter' ), 'IsMenu' => Array( 'title'=>'la_col_Visible', 'filter_block' => 'grid_options_filter' ), 'IsSystem' => Array( 'title'=>'la_col_System', 'filter_block' => 'grid_options_filter', ), 'Priority' => Array( 'title'=>'la_col_Priority', 'filter_block' => 'grid_options_filter', ), ), ), 'Radio' => Array ( 'Selector' => 'radio', 'Icons' => Array(1 => 'icon16_folder.gif', 0 => 'icon16_folder-red.gif'), 'Fields' => Array( 'CategoryId' => Array( 'title'=>'la_col_Id', 'data_block' => 'grid_radio_td', 'filter_block' => 'grid_range_filter', ), 'Name' => Array( 'title'=>'la_col_PageTitle', 'data_block' => 'page_browse_td', 'filter_block' => 'grid_like_filter'), 'Modified' => Array( 'title'=>'la_col_Modified', 'filter_block' => 'grid_date_range_filter' ), 'Template' => Array( 'title'=>'la_col_TemplateType', 'filter_block' => 'grid_options_filter' ), 'IsMenu' => Array( 'title'=>'la_col_Visible', 'filter_block' => 'grid_options_filter' ), 'IsSystem' => Array( 'title'=>'la_col_System', 'filter_block' => 'grid_options_filter', ), 'Priority' => Array( 'title'=>'la_col_Priority', 'filter_block' => 'grid_options_filter', ), ), ), 'Structure' => Array ( 'Icons' => Array(1 => 'icon16_folder.gif', 0 => 'icon16_folder-red.gif'), 'Fields' => Array( 'CategoryId' => Array( 'title'=>'la_col_Id', 'data_block' => 'grid_checkbox_td', 'filter_block' => 'grid_range_filter', ), 'Name' => Array( 'title'=>'la_col_PageTitle', 'data_block' => 'page_browse_td', 'filter_block' => 'grid_like_filter'), 'Modified' => Array( 'title'=>'la_col_Modified', 'filter_block' => 'grid_date_range_filter' ), 'Template' => Array( 'title'=>'la_col_TemplateType', 'filter_block' => 'grid_options_filter' ), 'IsMenu' => Array( 'title'=>'la_col_Visible', 'filter_block' => 'grid_options_filter' ), 'Path' => Array( 'title'=>'la_col_Path', 'data_block' => 'page_entercat_td', 'filter_block' => 'grid_like_filter' ), 'IsSystem' => Array( 'title'=>'la_col_System', 'filter_block' => 'grid_options_filter', ), 'Priority' => Array( 'title'=>'la_col_Priority', 'filter_block' => 'grid_options_filter', ), ), ), ), 'ConfigMapping' => Array ( 'PerPage' => 'Perpage_Category', 'ShortListPerPage' => 'Perpage_Category_Short', 'DefaultSorting1Field' => 'Category_Sortfield', 'DefaultSorting2Field' => 'Category_Sortfield2', 'DefaultSorting1Dir' => 'Category_Sortorder', 'DefaultSorting2Dir' => 'Category_Sortorder2', ), ); \ No newline at end of file Index: branches/RC/core/units/categories/categories_event_handler.php =================================================================== --- branches/RC/core/units/categories/categories_event_handler.php (revision 11896) +++ branches/RC/core/units/categories/categories_event_handler.php (revision 11897) @@ -1,1893 +1,1893 @@ <?php /** * @version $Id$ * @package In-Portal * @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved. * @license GNU/GPL * In-Portal is Open Source software. * This means that this software may have been modified pursuant * the GNU General Public License, and as distributed it includes * or is derivative of works licensed under the GNU General Public License * or other free or open source software licenses. * See http://www.in-portal.net/license/ for copyright notices and details. */ class CategoriesEventHandler extends kDBEventHandler { /** * Allows to override standart permission mapping * */ function mapPermissions() { parent::mapPermissions(); $permissions = Array ( 'OnRebuildCache' => Array ('self' => 'add|edit'), 'OnCopy' => Array ('self' => true), 'OnCut' => Array ('self' => 'edit'), 'OnPasteClipboard' => Array ('self' => true), 'OnPaste' => Array ('self' => 'add|edit', 'subitem' => 'edit'), 'OnRecalculatePriorities' => Array ('self' => 'add|edit'), // category ordering 'OnItemBuild' => Array ('self' => true), // always allow to view individual categories (regardless of CATEGORY.VIEW right) 'OnUpdatePreviewBlock' => Array ('self' => true), // for FCKEditor integration ); $this->permMapping = array_merge($this->permMapping, $permissions); } /** * Categories are sorted using special sorting event * */ function mapEvents() { parent::mapEvents(); $events_map = Array ( 'OnMassMoveUp' => 'OnChangePriority', 'OnMassMoveDown' => 'OnChangePriority', ); $this->eventMethods = array_merge($this->eventMethods, $events_map); } /** * Checks permissions of user * * @param kEvent $event */ function CheckPermission(&$event) { if (!$this->Application->IsAdmin()) { if ($event->Name == 'OnSetSortingDirect') { // allow sorting on front event without view permission return true; } if ($event->Name == 'OnItemBuild') { $category_id = $this->getPassedID($event); if ($category_id == 0) { return true; } } } if (in_array($event->Name, $this->_getMassPermissionEvents())) { $items = $this->_getPermissionCheckInfo($event); $perm_helper =& $this->Application->recallObject('PermissionsHelper'); /* @var $perm_helper kPermissionsHelper */ if (($event->Name == 'OnSave') && array_key_exists(0, $items)) { // adding new item (ID = 0) $perm_value = $perm_helper->AddCheckPermission($items[0]['ParentId'], $event->Prefix) > 0; } else { // leave only items, that can be edited $ids = Array (); $check_method = in_array($event->Name, Array ('OnMassDelete', 'OnCut')) ? 'DeleteCheckPermission' : 'ModifyCheckPermission'; foreach ($items as $item_id => $item_data) { if ($perm_helper->$check_method($item_data['CreatedById'], $item_data['ParentId'], $event->Prefix) > 0) { $ids[] = $item_id; } } if (!$ids) { // no items left for editing -> no permission return $perm_helper->finalizePermissionCheck($event, false); } $perm_value = true; $event->setEventParam('ids', $ids); // will be used later by "kDBEventHandler::StoreSelectedIDs" method } return $perm_helper->finalizePermissionCheck($event, $perm_value); } if ($event->Name == 'OnPasteClipboard') { // forces permission check to work by current category for "Paste In Category" operation $category_id = $this->Application->GetVar('m_cat_id'); $this->Application->SetVar('c_id', $category_id); } return parent::CheckPermission($event); } /** * Returns events, that require item-based (not just event-name based) permission check * * @return Array */ function _getMassPermissionEvents() { return Array ( 'OnEdit', 'OnSave', 'OnMassDelete', 'OnMassApprove', 'OnMassDecline', 'OnMassMoveUp', 'OnMassMoveDown', 'OnCut', ); } /** * Returns category item IDs, that require permission checking * * @param kEvent $event * @return string */ function _getPermissionCheckIDs(&$event) { if ($event->Name == 'OnSave') { $selected_ids = implode(',', $this->getSelectedIDs($event, true)); if (!$selected_ids) { $selected_ids = 0; // when saving newly created item (OnPreCreate -> OnPreSave -> OnSave) } } else { // OnEdit, OnMassDelete events, when items are checked in grid $selected_ids = implode(',', $this->StoreSelectedIDs($event)); } return $selected_ids; } /** * Returns information used in permission checking * * @param kEvent $event * @return Array */ function _getPermissionCheckInfo(&$event) { // when saving data from temp table to live table check by data from temp table $id_field = $this->Application->getUnitOption($event->Prefix, 'IDField'); $table_name = $this->Application->getUnitOption($event->Prefix, 'TableName'); if ($event->Name == 'OnSave') { $table_name = $this->Application->GetTempName($table_name, 'prefix:' . $event->Prefix); } $sql = 'SELECT ' . $id_field . ', CreatedById, ParentId FROM ' . $table_name . ' WHERE ' . $id_field . ' IN (' . $this->_getPermissionCheckIDs($event) . ')'; $items = $this->Conn->Query($sql, $id_field); if (!$items) { // when creating new category, then no IDs are stored in session $items_info = $this->Application->GetVar( $event->getPrefixSpecial(true) ); list ($id, $fields_hash) = each($items_info); if (array_key_exists('ParentId', $fields_hash)) { $item_category = $fields_hash['ParentId']; } else { $item_category = $this->Application->RecallVar('m_cat_id'); // saved in c:OnPreCreate event permission checking } $items[$id] = Array ( 'CreatedById' => $this->Application->RecallVar('user_id'), 'ParentId' => $item_category, ); } return $items; } /** * Set's mark, that root category is edited * * @param kEvent $event */ function OnEdit(&$event) { $category_id = $this->Application->GetVar($event->getPrefixSpecial().'_id'); $this->Application->StoreVar('IsRootCategory_'.$this->Application->GetVar('m_wid'), $category_id === '0'); parent::OnEdit($event); } /** * Adds selected link to listing * * @param kEvent $event */ function OnProcessSelected(&$event) { $object =& $event->getObject(); /* @var $object kDBItem */ $selected_ids = $this->Application->GetVar('selected_ids'); $this->RemoveRequiredFields($object); $object->SetDBField($this->Application->RecallVar('dst_field'), $selected_ids['c']); $object->Update(); $this->finalizePopup($event); } /** * Apply system filter to categories list * * @param kEvent $event */ function SetCustomQuery(&$event) { parent::SetCustomQuery($event); $object =& $event->getObject(); /* @var $object kDBList */ // don't show "Content" category in advanced view $object->addFilter('system_categories', '%1$s.Status <> 4'); // show system templates from current theme only + all virtual templates $object->addFilter('theme_filter', '%1$s.ThemeId = ' . $this->_getCurrentThemeId() . ' OR %1$s.ThemeId = 0'); if ($event->Special == 'showall') { // if using recycle bin don't show categories from there $recycle_bin = $this->Application->ConfigValue('RecycleBinFolder'); if ($recycle_bin) { $sql = 'SELECT TreeLeft, TreeRight FROM '.TABLE_PREFIX.'Category WHERE CategoryId = '.$recycle_bin; $tree_indexes = $this->Conn->GetRow($sql); $object->addFilter('recyclebin_filter', '%1$s.TreeLeft < '.$tree_indexes['TreeLeft'].' OR %1$s.TreeLeft > '.$tree_indexes['TreeRight']); } } if ($event->getEventParam('parent_cat_id') !== false) { $parent_cat_id = $event->getEventParam('parent_cat_id'); if ("$parent_cat_id" == 'Root') { $module_name = $event->getEventParam('module') ? $event->getEventParam('module') : 'In-Commerce'; $parent_cat_id = $this->Application->findModule('Name', $module_name, 'RootCat'); } } else { $parent_cat_id = $this->Application->GetVar('c_id'); if (!$parent_cat_id) { $parent_cat_id = $this->Application->GetVar('m_cat_id'); } if (!$parent_cat_id) { $parent_cat_id = 0; } } if ("$parent_cat_id" == '0') { // replace "0" category with "Content" category id (this way template $parent_cat_id = $this->Application->findModule('Name', 'Core', 'RootCat'); } if ("$parent_cat_id" != 'any') { if ($event->getEventParam('recursive')) { if ($parent_cat_id > 0) { // not "Home" category $tree_indexes = $this->Application->getTreeIndex($parent_cat_id); $object->addFilter('parent_filter', TABLE_PREFIX.'Category.TreeLeft BETWEEN '.$tree_indexes['TreeLeft'].' AND '.$tree_indexes['TreeRight']); } } else { $object->addFilter('parent_filter', 'ParentId = '.$parent_cat_id); } } $object->addFilter('perm_filter', 'PermId = 1'); // check for CATEGORY.VIEW permission if ($this->Application->RecallVar('user_id') != -1) { // apply permission filters to all users except "root" $groups = explode(',',$this->Application->RecallVar('UserGroups')); foreach ($groups as $group) { $view_filters[] = 'FIND_IN_SET('.$group.', acl)'; } $view_filter = implode(' OR ', $view_filters); $object->addFilter('perm_filter2', $view_filter); } if (!$this->Application->IsAdmin()) { // apply status filter only on front $object->addFilter('status_filter', $object->TableName.'.Status = 1'); } // process "types" and "except" parameters $type_clauses = Array(); $types = $event->getEventParam('types'); $types = $types ? explode(',', $types) : Array (); $except_types = $event->getEventParam('except'); $except_types = $except_types ? explode(',', $except_types) : Array (); if (in_array('related', $types) || in_array('related', $except_types)) { $related_to = $event->getEventParam('related_to'); if (!$related_to) { $related_prefix = $event->Prefix; } else { $sql = 'SELECT Prefix FROM '.TABLE_PREFIX.'ItemTypes WHERE ItemName = '.$this->Conn->qstr($related_to); $related_prefix = $this->Conn->GetOne($sql); } $rel_table = $this->Application->getUnitOption('rel', 'TableName'); $item_type = (int)$this->Application->getUnitOption($event->Prefix, 'ItemType'); if ($item_type == 0) { trigger_error('<strong>ItemType</strong> not defined for prefix <strong>' . $event->Prefix . '</strong>', E_USER_WARNING); } // process case, then this list is called inside another list $prefix_special = $event->getEventParam('PrefixSpecial'); if (!$prefix_special) { $prefix_special = $this->Application->Parser->GetParam('PrefixSpecial'); } $id = false; if ($prefix_special !== false) { $processed_prefix = $this->Application->processPrefix($prefix_special); if ($processed_prefix['prefix'] == $related_prefix) { // printing related categories within list of items (not on details page) $list =& $this->Application->recallObject($prefix_special); /* @var $list kDBList */ $id = $list->GetID(); } } if ($id === false) { // printing related categories for single item (possibly on details page) if ($related_prefix == 'c') { $id = $this->Application->GetVar('m_cat_id'); } else { $id = $this->Application->GetVar($related_prefix . '_id'); } } $p_item =& $this->Application->recallObject($related_prefix . '.current', null, Array('skip_autoload' => true)); $p_item->Load( (int)$id ); $p_resource_id = $p_item->GetDBField('ResourceId'); $sql = 'SELECT SourceId, TargetId FROM '.$rel_table.' WHERE (Enabled = 1) AND ( (Type = 0 AND SourceId = '.$p_resource_id.' AND TargetType = '.$item_type.') OR (Type = 1 AND ( (SourceId = '.$p_resource_id.' AND TargetType = '.$item_type.') OR (TargetId = '.$p_resource_id.' AND SourceType = '.$item_type.') ) ) )'; $related_ids_array = $this->Conn->Query($sql); $related_ids = Array(); foreach ($related_ids_array as $key => $record) { $related_ids[] = $record[ $record['SourceId'] == $p_resource_id ? 'TargetId' : 'SourceId' ]; } if (count($related_ids) > 0) { $type_clauses['related']['include'] = '%1$s.ResourceId IN ('.implode(',', $related_ids).')'; $type_clauses['related']['except'] = '%1$s.ResourceId NOT IN ('.implode(',', $related_ids).')'; } else { $type_clauses['related']['include'] = '0'; $type_clauses['related']['except'] = '1'; } $type_clauses['related']['having_filter'] = false; } if (in_array('category_related', $type_clauses)) { $object->removeFilter('parent_filter'); $resource_id = $this->Conn->GetOne(' SELECT ResourceId FROM '.$this->Application->getUnitOption($event->Prefix, 'TableName').' WHERE CategoryId = '.$parent_cat_id ); $sql = 'SELECT DISTINCT(TargetId) FROM '.TABLE_PREFIX.'Relationship WHERE SourceId = '.$resource_id.' AND SourceType = 1'; $related_cats = $this->Conn->GetCol($sql); $related_cats = is_array($related_cats) ? $related_cats : Array(); $sql = 'SELECT DISTINCT(SourceId) FROM '.TABLE_PREFIX.'Relationship WHERE TargetId = '.$resource_id.' AND TargetType = 1 AND Type = 1'; $related_cats2 = $this->Conn->GetCol($sql); $related_cats2 = is_array($related_cats2) ? $related_cats2 : Array(); $related_cats = array_unique( array_merge( $related_cats2, $related_cats ) ); if ($related_cats) { $type_clauses['category_related']['include'] = '%1$s.ResourceId IN ('.implode(',', $related_cats).')'; $type_clauses['category_related']['except'] = '%1$s.ResourceId NOT IN ('.implode(',', $related_cats).')'; } else { $type_clauses['category_related']['include'] = '0'; $type_clauses['category_related']['except'] = '1'; } $type_clauses['category_related']['having_filter'] = false; } if (in_array('product_related', $types)) { $object->removeFilter('parent_filter'); $product_id = $event->getEventParam('product_id') ? $event->getEventParam('product_id') : $this->Application->GetVar('p_id'); $resource_id = $this->Conn->GetOne(' SELECT ResourceId FROM '.$this->Application->getUnitOption('p', 'TableName').' WHERE ProductId = '.$product_id ); $sql = 'SELECT DISTINCT(TargetId) FROM '.TABLE_PREFIX.'Relationship WHERE SourceId = '.$resource_id.' AND TargetType = 1'; $related_cats = $this->Conn->GetCol($sql); $related_cats = is_array($related_cats) ? $related_cats : Array(); $sql = 'SELECT DISTINCT(SourceId) FROM '.TABLE_PREFIX.'Relationship WHERE TargetId = '.$resource_id.' AND SourceType = 1 AND Type = 1'; $related_cats2 = $this->Conn->GetCol($sql); $related_cats2 = is_array($related_cats2) ? $related_cats2 : Array(); $related_cats = array_unique( array_merge( $related_cats2, $related_cats ) ); if ($related_cats) { $type_clauses['product_related']['include'] = '%1$s.ResourceId IN ('.implode(',', $related_cats).')'; $type_clauses['product_related']['except'] = '%1$s.ResourceId NOT IN ('.implode(',', $related_cats).')'; } else { $type_clauses['product_related']['include'] = '0'; $type_clauses['product_related']['except'] = '1'; } $type_clauses['product_related']['having_filter'] = false; } $type_clauses['menu']['include'] = '%1$s.IsMenu = 1'; $type_clauses['menu']['except'] = '%1$s.IsMenu = 0'; $search_helper =& $this->Application->recallObject('SearchHelper'); /* @var $search_helper kSearchHelper */ $search_helper->SetComplexFilter($event, $type_clauses, implode(',', $types), implode(',', $except_types)); } /** * Returns current theme id * * @return int */ function _getCurrentThemeId() { $themes_helper =& $this->Application->recallObject('ThemesHelper'); /* @var $themes_helper kThemesHelper */ return (int)$themes_helper->getCurrentThemeId(); } /** * Enter description here... * * @param kEvent $event * @return int */ function getPassedID(&$event) { if (($event->Special == 'page') || ($event->Special == '-virtual') || ($event->Prefix == 'st')) { return $this->_getPassedStructureID($event); } if ($this->Application->IsAdmin()) { return parent::getPassedID($event); } return $this->Application->GetVar('m_cat_id'); } /** * Enter description here... * * @param kEvent $event * @return int */ function _getPassedStructureID(&$event) { static $page_by_template = Array (); if ($event->Special == 'current') { return $this->Application->GetVar('m_cat_id'); } $event->setEventParam('raise_warnings', 0); $page_id = parent::getPassedID($event); if ($page_id === false) { $template = $event->getEventParam('page'); if (!$template) { $template = $this->Application->GetVar('t'); } // bug: when template contains "-" symbols (or others, that stripDisallowed will replace) it's not found if (!array_key_exists($template, $page_by_template)) { $sql = 'SELECT ' . $this->Application->getUnitOption($event->Prefix, 'IDField') . ' FROM ' . $this->Application->getUnitOption($event->Prefix, 'TableName') . ' WHERE ( (NamedParentPath = ' . $this->Conn->qstr($template) . ') OR (NamedParentPath = ' . $this->Conn->qstr('Content/' . $template) . ') OR (IsSystem = 1 AND CachedTemplate = ' . $this->Conn->qstr($template) . ') ) AND (ThemeId = ' . $this->_getCurrentThemeId() . ' OR ThemeId = 0)'; $page_id = $this->Conn->GetOne($sql); } else { $page_id = $page_by_template[$template]; } if ($page_id === false && EDITING_MODE) { // create missing pages, when in editing mode $object =& $this->Application->recallObject($this->Prefix . '.-new', null, Array('skip_autoload' => true)); /* @var $object kDBItem */ $created = $this->_prepareAutoPage($object, $template, null, SMS_MODE_AUTO, false); // create virtual (not system!) page if ($created) { if ($this->Application->ConfigValue('QuickCategoryPermissionRebuild') || !$this->Application->IsAdmin()) { $updater =& $this->Application->recallObject('kPermCacheUpdater'); /* @var $updater kPermCacheUpdater */ $updater->OneStepRun(); } $event->CallSubEvent('OnResetMenuCache'); $this->Application->RemoveVar('PermCache_UpdateRequired'); $page_id = $object->GetID(); $this->Application->SetVar('m_cat_id', $page_id); } } if ($page_id) { $page_by_template[$template] = $page_id; } } if (!$page_id && !$this->Application->IsAdmin()) { $page_id = $this->Application->GetVar('m_cat_id'); } return $page_id; } function ParentGetPassedId(&$event) { return parent::GetPassedId($event); } /** * Adds calculates fields for item statuses * * @param kCatDBItem $object * @param kEvent $event */ function prepareObject(&$object, &$event) { $object =& $event->getObject( Array('skip_autoload' => true) ); $object->addCalculatedField( 'IsNew', ' IF(%1$s.NewItem = 2, IF(%1$s.CreatedOn >= (UNIX_TIMESTAMP() - '. $this->Application->ConfigValue('Category_DaysNew'). '*3600*24), 1, 0), %1$s.NewItem )'); } /** * Set correct parent path for newly created categories * * @param kEvent $event */ function OnAfterCopyToLive(&$event) { $parent_path = false; $object =& $this->Application->recallObject($event->Prefix.'.-item', null, Array('skip_autoload' => true, 'live_table' => true)); $object->Load($event->getEventParam('id')); if ($event->getEventParam('temp_id') == 0) { if ($object->isLoaded()) { // update path only for real categories (not including "Home" root category) $fields_hash = Array('ParentPath' => $object->buildParentPath()); $this->Conn->doUpdate($fields_hash, $object->TableName, 'CategoryId = '.$object->GetID()); $parent_path = $fields_hash['ParentPath']; } } else { $parent_path = $object->GetDBField('ParentPath'); } if ($parent_path) { $cache_updater =& $this->Application->recallObject('kPermCacheUpdater', null, array('strict_path' => $parent_path)); $cache_updater->OneStepRun(); $cache_updater->StrictPath = false; } } /** * Set cache modification mark if needed * * @param kEvent $event */ function OnBeforeDeleteFromLive(&$event) { $id = $event->getEventParam('id'); // loding anyway, because this object is needed by "c-perm:OnBeforeDeleteFromLive" event $temp_object =& $event->getObject( Array('skip_autoload' => true) ); $temp_object->Load($id); if ($id == 0) { if ($temp_object->isLoaded()) { // new category -> update cache (not loaded when "Home" category) $this->Application->StoreVar('PermCache_UpdateRequired', 1); } return ; } // existing category was edited, check if in-cache fields are modified $live_object =& $this->Application->recallObject($event->Prefix.'.-item', null, Array('live_table' => true, 'skip_autoload' => true)); $live_object->Load($id); $cached_fields = Array('Name', 'Filename', 'Template', 'ParentId', 'Priority'); foreach ($cached_fields as $cached_field) { if ($live_object->GetDBField($cached_field) != $temp_object->GetDBField($cached_field)) { // use session instead of REQUEST because of permission editing in category can contain // multiple submits, that changes data before OnSave event occurs $this->Application->StoreVar('PermCache_UpdateRequired', 1); break; } } } /** * Calls kDBEventHandler::OnSave original event * Used in proj-cms:StructureEventHandler->OnSave * * @param kEvent $event */ function parentOnSave(&$event) { parent::OnSave($event); } /** * Reset root-category flag when new category is created * * @param kEvent $event */ function OnPreCreate(&$event) { // 1. for permission editing of Home category $this->Application->RemoveVar('IsRootCategory_' . $this->Application->GetVar('m_wid')); parent::OnPreCreate($event); $object =& $event->getObject(); // 2. preset template // $object->SetDBField('Template', $this->_getDefaultDesign()); $priority_helper =& $this->Application->recallObject('PriorityHelper'); /* @var $priority_helper kPriorityHelper */ // 3. prepare priorities dropdown $category_id = $this->Application->GetVar('m_cat_id'); $priority_helper->preparePriorities($event, true, 'ParentId = ' . $category_id); } /** * Checks cache update mark and redirect to cache if needed * * @param kEvent $event */ function OnSave(&$event) { $object =& $event->getObject(); if ($object->IsRoot()) { $event->setEventParam('master_ids', Array(0)); $this->RemoveRequiredFields($object); } parent::OnSave($event); if ($event->status != erSUCCESS) { return ; } // 1. update priorities $tmp = $this->Application->RecallVar('priority_changes'.$this->Application->GetVar('m_wid')); $changes = $tmp ? unserialize($tmp) : Array (); $changed_ids = array_keys($changes); $priority_helper =& $this->Application->recallObject('PriorityHelper'); /* @var $priority_helper kPriorityHelper */ $priority_helper->updatePriorities($event, $changes, Array (0 => $event->getEventParam('ids'))); if ($this->Application->RecallVar('PermCache_UpdateRequired')) { $this->Application->RemoveVar('IsRootCategory_' . $this->Application->GetVar('m_wid')); } $this->Application->StoreVar('RefreshStructureTree', 1); $event->CallSubEvent('OnResetMenuCache'); } /** * Creates a new item in temp table and * stores item id in App vars and Session on succsess * * @param kEvent $event */ function OnPreSaveCreated(&$event) { $object =& $event->getObject( Array('skip_autoload' => true) ); /* @var $object CategoriesItem */ if ($object->IsRoot()) { // don't create root category while saving permissions return ; } $priority_helper =& $this->Application->recallObject('PriorityHelper'); /* @var $priority_helper kPriorityHelper */ $category_id = $this->Application->GetVar('m_cat_id'); $priority_helper->preparePriorities($event, true, 'ParentId = ' . $category_id); parent::OnPreSaveCreated($event); } /** * Deletes sym link to other category * * @param kEvent $event */ function OnAfterItemDelete(&$event) { parent::OnAfterItemDelete($event); $object =& $event->getObject(); /* @var $object kDBItem */ $sql = 'UPDATE '.$object->TableName.' SET SymLinkCategoryId = NULL WHERE SymLinkCategoryId = '.$object->GetID(); $this->Conn->Query($sql); } /** * Exclude root categories from deleting * * @param kEvent $event */ function customProcessing(&$event, $type) { if ($event->Name == 'OnMassDelete' && $type == 'before') { $ids = $event->getEventParam('ids'); if (!$ids || $this->Application->ConfigValue('AllowDeleteRootCats')) { return ; } // get module root categories and exclude them foreach ($this->Application->ModuleInfo as $module_info) { $root_categories[] = $module_info['RootCat']; } $root_categories = array_unique($root_categories); if ($root_categories && array_intersect($ids, $root_categories)) { $event->setEventParam('ids', array_diff($ids, $root_categories)); $this->Application->StoreVar('root_delete_error', 1); } } $change_events = Array ('OnPreSave', 'OnPreSaveCreated', 'OnUpdate', 'OnSave'); if ($type == 'after' && in_array($event->Name, $change_events)) { $object =& $event->getObject(); $tmp = $this->Application->RecallVar('priority_changes'.$this->Application->GetVar('m_wid')); $changes = $tmp ? unserialize($tmp) : array(); if (!isset($changes[$object->GetID()])) { $changes[$object->GetId()]['old'] = $object->GetID() == 0 ? 'new' : $object->GetDBField('OldPriority'); } if ($changes[$object->GetId()]['old'] == $object->GetDBField('Priority')) return ; $changes[$object->GetId()]['new'] = $object->GetDBField('Priority'); $changes[$object->GetId()]['parent'] = $object->GetDBField('ParentId'); $this->Application->StoreVar('priority_changes'.$this->Application->GetVar('m_wid'), serialize($changes)); } } /** * Checks, that given template exists (physically) in given theme * * @param string $template * @param int $theme_id * @return bool */ function _templateFound($template, $theme_id = null) { static $init_made = false; if (!$init_made) { $this->Application->InitParser(true); $init_made = true; } if (!isset($theme_id)) { $theme_id = $this->_getCurrentThemeId(); } $theme_name = $this->_getThemeName($theme_id); return $this->Application->TemplatesCache->TemplateExists('theme:' . $theme_name . '/' . $template); } /** * Removes ".tpl" in template path * * @param string $template * @return string */ function _stripTemplateExtension($template) { // return preg_replace('/\.[^.\\\\\\/]*$/', '', $template); return preg_replace('/^[\\/]{0,1}(.*)\.tpl$/', "$1", $template); } /** * Deletes all selected items. * Automatically recurse into sub-items using temp handler, and deletes sub-items * by calling its Delete method if sub-item has AutoDelete set to true in its config file * * @param kEvent $event */ function OnMassDelete(&$event) { if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) { return; } $ids = $this->StoreSelectedIDs($event); $to_delete = array(); if ($recycle_bin = $this->Application->ConfigValue('RecycleBinFolder')) { $rb =& $this->Application->recallObject('c.recycle', null, Array ('skip_autoload' => true)); $rb->Load($recycle_bin); $cat =& $event->getObject(Array('skip_autoload' => true)); foreach ($ids as $id) { $cat->Load($id); if (preg_match('/^'.preg_quote($rb->GetDBField('ParentPath'),'/').'/', $cat->GetDBField('ParentPath'))) { $to_delete[] = $id; continue; } $cat->SetDBField('ParentId', $recycle_bin); $cat->Update(); } $ids = $to_delete; $event->redirect = 'categories/cache_updater'; } $event->setEventParam('ids', $ids); $this->customProcessing($event, 'before'); $ids = $event->getEventParam('ids'); if ($ids) { $recursive_helper =& $this->Application->recallObject('RecursiveHelper'); /* @var $recursive_helper kRecursiveHelper */ foreach ($ids as $id) { $recursive_helper->DeleteCategory($id, $event->Prefix); } } $this->clearSelectedIDs($event); // update priorities $priority_helper =& $this->Application->recallObject('PriorityHelper'); /* @var $priority_helper kPriorityHelper */ // after deleting categories, all priorities should be recalculated $parent_id = $this->Application->GetVar('m_cat_id'); $priority_helper->recalculatePriorities($event, 'ParentId = ' . $parent_id); $this->Application->StoreVar('RefreshStructureTree', 1); $event->CallSubEvent('OnResetMenuCache'); } /** * Add selected items to clipboard with mode = COPY (CLONE) * * @param kEvent $event */ function OnCopy(&$event) { $this->Application->RemoveVar('clipboard'); $clipboard_helper =& $this->Application->recallObject('ClipboardHelper'); $clipboard_helper->setClipboard($event, 'copy', $this->StoreSelectedIDs($event)); $this->clearSelectedIDs($event); } /** * Add selected items to clipboard with mode = CUT * * @param kEvent $event */ function OnCut(&$event) { $this->Application->RemoveVar('clipboard'); $clipboard_helper =& $this->Application->recallObject('ClipboardHelper'); $clipboard_helper->setClipboard($event, 'cut', $this->StoreSelectedIDs($event)); $this->clearSelectedIDs($event); } /** * Controls all item paste operations. Can occur only with filled clipbord. * * @param kEvent $event */ function OnPasteClipboard(&$event) { $clipboard = unserialize( $this->Application->RecallVar('clipboard') ); foreach ($clipboard as $prefix => $clipboard_data) { $paste_event = new kEvent($prefix.':OnPaste', Array('clipboard_data' => $clipboard_data)); $this->Application->HandleEvent($paste_event); $event->redirect = $paste_event->redirect; $event->redirect_params = $paste_event->redirect_params; $event->status = $paste_event->status; } } /** * Checks permission for OnPaste event * * @param kEvent $event * @return bool */ function _checkPastePermission(&$event) { $perm_helper =& $this->Application->recallObject('PermissionsHelper'); /* @var $perm_helper kPermissionsHelper */ $category_id = $this->Application->GetVar('m_cat_id'); if ($perm_helper->AddCheckPermission($category_id, $event->Prefix) == 0) { // no items left for editing -> no permission return $perm_helper->finalizePermissionCheck($event, false); } return true; } /** * Paste categories with subitems from clipboard * * @param kEvent $event */ function OnPaste(&$event) { if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1) || !$this->_checkPastePermission($event)) { return ; } $clipboard_data = $event->getEventParam('clipboard_data'); if (!$clipboard_data['cut'] && !$clipboard_data['copy']) { return false; } // 1. get ParentId of moved category(-es) before it gets updated!!!) $id_field = $this->Application->getUnitOption($event->Prefix, 'IDField'); if ($clipboard_data['cut']) { $sql = 'SELECT ParentId FROM ' . $this->Application->getUnitOption($event->Prefix, 'TableName') . ' WHERE ' . $id_field . ' = ' . $clipboard_data['cut'][0]; $source_category_id = $this->Conn->GetOne($sql); } $recursive_helper =& $this->Application->recallObject('RecursiveHelper'); /* @var $recursive_helper kRecursiveHelper */ if ($clipboard_data['cut']) { $recursive_helper->MoveCategories($clipboard_data['cut'], $this->Application->GetVar('m_cat_id')); } if ($clipboard_data['copy']) { foreach ($clipboard_data['copy'] as $id) { $recursive_helper->PasteCategory($id, $event->Prefix); } } $priority_helper =& $this->Application->recallObject('PriorityHelper'); /* @var $priority_helper kPriorityHelper */ if ($clipboard_data['cut']) { $priority_helper->recalculatePriorities($event, 'ParentId = '.$source_category_id); } // recalculate priorities of newly pasted categories in destination category $parent_id = $this->Application->GetVar('m_cat_id'); $priority_helper->recalculatePriorities($event, 'ParentId = ' . $parent_id); if ($clipboard_data['cut'] || $clipboard_data['copy']) { // rebuild with progress bar if ($this->Application->ConfigValue('QuickCategoryPermissionRebuild')) { $updater =& $this->Application->recallObject('kPermCacheUpdater'); /* @var $updater kPermCacheUpdater */ $updater->OneStepRun(); } else { $event->redirect = 'categories/cache_updater'; } $event->CallSubEvent('OnResetMenuCache'); $this->Application->StoreVar('RefreshStructureTree', 1); } } /** * Occurs when pasting category * * @param kEvent $event */ /*function OnCatPaste(&$event) { $inp_clipboard = $this->Application->RecallVar('ClipBoard'); $inp_clipboard = explode('-', $inp_clipboard, 2); if($inp_clipboard[0] == 'COPY') { $saved_cat_id = $this->Application->GetVar('m_cat_id'); $cat_ids = $event->getEventParam('cat_ids'); $id_field = $this->Application->getUnitOption($event->Prefix, 'IDField'); $table = $this->Application->getUnitOption($event->Prefix, 'TableName'); $ids_sql = 'SELECT '.$id_field.' FROM '.$table.' WHERE ResourceId IN (%s)'; $resource_ids_sql = 'SELECT ItemResourceId FROM '.TABLE_PREFIX.'CategoryItems WHERE CategoryId = %s AND PrimaryCat = 1'; $object =& $this->Application->recallObject($event->Prefix.'.item', $event->Prefix, Array('skip_autoload' => true)); foreach($cat_ids as $source_cat => $dest_cat) { $item_resource_ids = $this->Conn->GetCol( sprintf($resource_ids_sql, $source_cat) ); if(!$item_resource_ids) continue; $this->Application->SetVar('m_cat_id', $dest_cat); $item_ids = $this->Conn->GetCol( sprintf($ids_sql, implode(',', $item_resource_ids) ) ); $temp =& $this->Application->recallObject($event->getPrefixSpecial().'_TempHandler', 'kTempTablesHandler'); if($item_ids) $temp->CloneItems($event->Prefix, $event->Special, $item_ids); } $this->Application->SetVar('m_cat_id', $saved_cat_id); } }*/ /** * Cleares clipboard content * * @param kEvent $event */ function OnClearClipboard(&$event) { $this->Application->RemoveVar('clipboard'); } /** * Sets correct status for new categories created on front-end * * @param kEvent $event */ function OnBeforeItemCreate(&$event) { $this->_beforeItemChange($event); if ($this->Application->IsAdmin() || $event->Prefix == 'st') { // don't check category permissions when auto-creating structure pages return ; } $perm_helper =& $this->Application->recallObject('PermissionsHelper'); /* @var $perm_helper kPermissionsHelper */ $new_status = false; $category_id = $this->Application->GetVar('m_cat_id'); if ($perm_helper->CheckPermission('CATEGORY.ADD', 0, $category_id)) { $new_status = STATUS_ACTIVE; } else if ($perm_helper->CheckPermission('CATEGORY.ADD.PENDING', 0, $category_id)) { $new_status = STATUS_PENDING; } if ($new_status) { $object =& $event->getObject(); /* @var $object kDBItem */ $object->SetDBField('Status', $new_status); /* if (!$this->Application->IsAdmin()) { $object->SetDBField('IsMenu', 0); // add all suggested categories as non-menu } */ } else { $event->status = erPERM_FAIL; return ; } } /** * Sets correct status for new categories created on front-end * * @param kEvent $event */ function OnBeforeItemUpdate(&$event) { parent::OnBeforeItemUpdate($event); $this->_beforeItemChange($event); } /** * Performs redirect to correct suggest confirmation template * * @param kEvent $event */ function OnCreate(&$event) { parent::OnCreate($event); if ($this->Application->IsAdmin() || $event->status != erSUCCESS) { return ; } $object =& $event->getObject(); $cache_updater =& $this->Application->recallObject('kPermCacheUpdater', null, array('strict_path' => $object->GetDBField('ParentPath'))); $cache_updater->OneStepRun(); $cache_updater->StrictPath = false; $is_active = ($object->GetDBField('Status') == STATUS_ACTIVE); $next_template = $is_active ? 'suggest_confirm_template' : 'suggest_pending_confirm_template'; $event->redirect = $this->Application->GetVar($next_template); $event->SetRedirectParam('opener', 's'); // send email events $perm_prefix = $this->Application->getUnitOption($event->Prefix, 'PermItemPrefix'); $event_suffix = $is_active ? 'ADD' : 'ADD.PENDING'; $this->Application->EmailEventAdmin($perm_prefix.'.'.$event_suffix); $this->Application->EmailEventUser($perm_prefix.'.'.$event_suffix, $object->GetDBField('CreatedById')); } /** * Returns current per-page setting for list * * @param kEvent $event * @return int */ function getPerPage(&$event) { if (!$this->Application->IsAdmin()) { $event->setEventParam('same_special', true); } return parent::getPerPage($event); } /** * Set's correct page for list * based on data provided with event * * @param kEvent $event * @access private * @see OnListBuild */ function SetPagination(&$event) { parent::SetPagination($event); if (!$this->Application->IsAdmin()) { $page_var = $event->getEventParam('page_var'); if ($page_var !== false) { $page = $this->Application->GetVar($page_var); if (is_numeric($page)) { $object =& $event->getObject(); $object->SetPage($page); } } } } /** * Apply same processing to each item beeing selected in grid * * @param kEvent $event * @access private */ function iterateItems(&$event) { if ($event->Name != 'OnMassApprove' && $event->Name != 'OnMassDecline') { return parent::iterateItems($event); } if ($this->Application->CheckPermission('SYSTEM_ACCESS.READONLY', 1)) { return; } $object =& $event->getObject( Array('skip_autoload' => true) ); $ids = $this->StoreSelectedIDs($event); if ($ids) { $status_field = array_shift( $this->Application->getUnitOption($event->Prefix,'StatusField') ); foreach ($ids as $id) { $object->Load($id); switch ($event->Name) { case 'OnMassApprove': $object->SetDBField($status_field, 1); break; case 'OnMassDecline': $object->SetDBField($status_field, 0); break; } if ($this->Application->GetVar('propagate_category_status')) { $sql = 'UPDATE '.$object->TableName.' SET '.$status_field.' = '.$object->GetDBField($status_field).' WHERE TreeLeft BETWEEN '.$object->GetDBField('TreeLeft').' AND '.$object->GetDBField('TreeRight'); $this->Conn->Query($sql); } if ($object->Update()) { $event->status = erSUCCESS; } else { $event->status = erFAIL; $event->redirect = false; break; } } } $this->clearSelectedIDs($event); $this->Application->StoreVar('RefreshStructureTree', 1); } /** * Checks, that currently loaded item is allowed for viewing (non permission-based) * * @param kEvent $event * @return bool */ function checkItemStatus(&$event) { $status_fields = $this->Application->getUnitOption($event->Prefix,'StatusField'); if (!$status_fields) { return true; } $status_field = array_shift($status_fields); if ($status_field == 'Status' || $status_field == 'Enabled') { $object =& $event->getObject(); if (!$object->isLoaded()) { return true; } return $object->GetDBField($status_field) == STATUS_ACTIVE || $object->GetDBField($status_field) == 4; } return true; } // ============= for cms page processing ======================= /** * Returns default design template * * @return string */ function _getDefaultDesign() { $default_design = $this->Application->ConfigValue('cms_DefaultDesign'); return '/' . trim($default_design ? $default_design : 'designs/default_design', '/'); } /** * Returns default design based on given virtual template (used from kApplication::Run) * * @return string */ function GetDesignTemplate($t = null) { if (!isset($t)) { $t = $this->Application->GetVar('t'); } $page =& $this->Application->recallObject($this->Prefix . '.-virtual', null, Array ('page' => $t)); if($page->isLoaded()) { $real_t = $page->GetDBField('CachedTemplate'); $this->Application->SetVar('m_cat_id', $page->GetDBField('CategoryId') ); if ($page->GetDBField('FormId')) { $this->Application->SetVar('form_id', $page->GetDBField('FormId')); } } else { $real_t = $this->_getDefaultDesign(); } // $this->Application->SetVar('t', $t); return $real_t; } /** * Sets category id based on found template (used from kApplication::Run) * * @deprecated */ /*function SetCatByTemplate() { $t = $this->Application->GetVar('t'); $page =& $this->Application->recallObject($this->Prefix . '.-virtual'); if ($page->isLoaded()) { $this->Application->SetVar('m_cat_id', $page->GetDBField('CategoryId') ); } }*/ /** * Prepares template paths * * @param kEvent $event */ function _beforeItemChange(&$event) { $object =& $event->getObject(); /* @var $object kDBItem */ $object->SetDBField('Template', $this->_stripTemplateExtension( $object->GetDBField('Template') )); if ($object->GetDBField('IsSystem') == 1) { if (!$this->_templateFound($object->GetDBField('Template'), $object->GetDBField('ThemeId'))) { $object->SetError('Template', 'template_file_missing', 'la_error_TemplateFileMissing'); } } $this->_saveTitleField($object, 'Title'); $this->_saveTitleField($object, 'MenuTitle'); } /** * Sets page name to requested field in case when: * 1. page was auto created (through theme file rebuld) * 2. requested field is emtpy * * @param kDBItem $object * @param string $field * @author Alex */ function _saveTitleField(&$object, $field) { - $value = $object->GetField($field); + $value = $object->GetField($field, 'no_default'); if ($value == '' || preg_match('/^_Auto: (.*)/', $value)) { $ml_formatter =& $this->Application->recallObject('kMultiLanguage'); /* @var $ml_formatter kMultiLanguage */ $object->SetField( $ml_formatter->LangFieldName($field), $object->GetField( $ml_formatter->LangFieldName('Name') ) ); } } /** * Don't allow to delete system pages, when not in debug mode * * @param kEvent $event */ function OnBeforeItemDelete(&$event) { $object =& $event->getObject(); if ($object->GetDBField('IsSystem') && !$this->Application->isDebugMode()) { $event->status = erFAIL; } } /** * Enter description here... * * @param StructureItem $object * @param string $template */ function _prepareAutoPage(&$object, $template, $theme_id = null, $system_mode = SMS_MODE_AUTO, $template_info = Array ()) { $template = $this->_stripTemplateExtension($template); if ($system_mode == SMS_MODE_AUTO) { $system = $this->_templateFound($template, $theme_id) ? 1 : 0; } else { $system = $system_mode == SMS_MODE_FORCE ? 1 : 0; } if ($system && $template_info === false) { // do not autocreate system pages, when browsing through site return false; } if (!isset($theme_id)) { $theme_id = $this->_getCurrentThemeId(); } $root_category = $this->Application->findModule('Name', 'Core', 'RootCat'); $page_category = $this->Application->GetVar('m_cat_id'); if (!$page_category) { $page_category = $root_category; $this->Application->SetVar('m_cat_id', $page_category); } if (!$system && strpos($template, '/') !== false) { // virtual page, but have "/" in template path -> create it's path $category_path = explode('/', $template); $template = array_pop($category_path); $page_category = $this->_getParentCategoryFromPath($category_path, $root_category, $theme_id); } $page_name = $system ? '_Auto: ' . $template : $template; $page_description = ''; if ($system) { $design_template = strtolower($template); // leading "/" not added ! if ($template_info) { if (array_key_exists('name', $template_info) && $template_info['name']) { $page_name = $template_info['name']; } if (array_key_exists('desc', $template_info) && $template_info['desc']) { $page_description = $template_info['desc']; } if (array_key_exists('section', $template_info) && $template_info['section']) { // this will override any global "m_cat_id" $page_category = $this->_getParentCategoryFromPath(explode('||', $template_info['section']), $root_category, $theme_id); } } } else { $design_template = $this->_getDefaultDesign(); // leading "/" added ! } // put all templates to then end of list (in their category) $sql = 'SELECT MIN(Priority) FROM ' . $object->TableName . ' WHERE ParentId = ' . $page_category; $min_priority = (int)$this->Conn->GetOne($sql); $object->Clear(); $object->SetDBField('ParentId', $page_category); $object->SetDBField('IsSystem', $system); // system templates don't build their NamedParentPath based on their location because they are all added under // "Content" when theme file structure is rebuilded and for ex. file "in-edit/designs/general" will have filename // (after stripDisallowed) like "in_edit_designs_general" witch is less readable like "in-edit/designs/general" // as for now. // TODO: 1. make system template NamedParentPath dependent on their location in structure. // 2. load cms-page not only by NamedParentPath, but also by 'OR (Template = "$template" AND IsSystem = 1)' // This way we can store CMS-blocks based on system template name on HDD no matter where it's location is // and we can address him from template using his system path OR structure path (CMS-blocks should work too). $object->SetDBField('IsMenu', 0); $object->SetDBField('ThemeId', $system ? $theme_id : 0); $object->SetDBField('Priority', $min_priority - 1); $object->SetDBField('Template', $design_template); $object->SetDBField('CachedTemplate', $design_template); $primary_language = $this->Application->GetDefaultLanguageId(); $current_language = $this->Application->GetVar('m_lang'); $object->SetDBField('l' . $primary_language . '_Name', $page_name); $object->SetDBField('l' . $current_language . '_Name', $page_name); $object->SetDBField('l' . $primary_language . '_Description', $page_description); $object->SetDBField('l' . $current_language . '_Description', $page_description); return $object->Create(); } function _getParentCategoryFromPath($category_path, $base_category, $theme_id = null) { static $category_ids = Array (); if (!$category_path) { return $base_category; } if (array_key_exists(implode('||', $category_path), $category_ids)) { return $category_ids[ implode('||', $category_path) ]; } $backup_category_id = $this->Application->GetVar('m_cat_id'); $object =& $this->Application->recallObject($this->Prefix . '.-item', null, Array ('skip_autoload' => true)); /* @var $object kDBItem */ $parent_id = $base_category; $filenames_helper =& $this->Application->recallObject('FilenamesHelper'); /* @var $filenames_helper kFilenamesHelper */ $safe_category_path = array_map(Array (&$filenames_helper, 'replaceSequences'), $category_path); foreach ($category_path as $category_order => $category_name) { $this->Application->SetVar('m_cat_id', $parent_id); // get virtual category first, when possible $sql = 'SELECT ' . $object->IDField . ' FROM ' . $object->TableName . ' WHERE ( Filename = ' . $this->Conn->qstr($safe_category_path[$category_order]) . ' OR Filename = ' . $this->Conn->qstr( $filenames_helper->replaceSequences('_Auto: ' . $category_name) ) . ' ) AND (ParentId = ' . $parent_id . ') AND (ThemeId = 0 OR ThemeId = ' . $theme_id . ') ORDER BY ThemeId ASC'; $parent_id = $this->Conn->GetOne($sql); if ($parent_id === false) { // page not found $template = implode('/', array_slice($safe_category_path, 0, $category_order + 1)); // don't process system templates in sub-categories $system = $this->_templateFound($template, $theme_id) && (strpos($template, '/') === false); if (!$this->_prepareAutoPage($object, $category_name, $theme_id, $system ? SMS_MODE_FORCE : false)) { // page was not created break; } $parent_id = $object->GetID(); } } $this->Application->SetVar('m_cat_id', $backup_category_id); $category_ids[ implode('||', $category_path) ] = $parent_id; return $parent_id; } /** * Returns theme name by it's id. Used in structure page creation. * * @param int $theme_id * @return string */ function _getThemeName($theme_id) { static $themes = null; if (!isset($themes)) { $id_field = $this->Application->getUnitOption('theme', 'IDField'); $table_name = $this->Application->getUnitOption('theme', 'TableName'); $sql = 'SELECT Name, ' . $id_field . ' FROM ' . $table_name . ' WHERE Enabled = 1'; $themes = $this->Conn->GetCol($sql, $id_field); } return array_key_exists($theme_id, $themes) ? $themes[$theme_id] : false; } /** * Resets SMS-menu cache * * @param kEvent $event */ function OnResetMenuCache(&$event) { $this->Conn->Query('DELETE FROM '.TABLE_PREFIX.'Cache WHERE VarName IN ("cms_menu", "StructureTree")'); } /** * Updates structure config * * @param kEvent $event */ function OnAfterConfigRead(&$event) { parent::OnAfterConfigRead($event); if (defined('IS_INSTALL') && IS_INSTALL) { // skip any processing, because Category table doesn't exists until install is finished return ; } $root_category = $this->Application->findModule('Name', 'Core', 'RootCat'); // set root category $section_ajustments = $this->Application->getUnitOption($event->Prefix, 'SectionAdjustments'); $section_ajustments['in-portal:browse'] = Array ( 'url' => Array ('m_cat_id' => $root_category), 'late_load' => Array ('m_cat_id' => $root_category), 'onclick' => 'checkCatalog(' . $root_category . ')', ); $this->Application->setUnitOption($event->Prefix, 'SectionAdjustments', $section_ajustments); // prepare structure dropdown $category_helper =& $this->Application->recallObject('CategoryHelper'); /* @var $category_helper CategoryHelper */ $fields = $this->Application->getUnitOption($event->Prefix, 'Fields'); $fields['ParentId']['default'] = (int)$this->Application->GetVar('m_cat_id'); $fields['ParentId']['options'] = $category_helper->getStructureTreeAsOptions(); // limit design list by theme $design_folders = Array ('tf.FilePath = "/designs"', 'tf.FilePath = "/platform/designs"'); foreach ($this->Application->ModuleInfo as $module_name => $module_info) { $design_folders[] = 'tf.FilePath = "/' . $module_info['TemplatePath'] . 'designs"'; } $design_folders = array_unique($design_folders); $theme_id = $this->_getCurrentThemeId(); $design_sql = $fields['Template']['options_sql']; $design_sql = str_replace('(tf.FilePath = "/designs")', '(' . implode(' OR ', $design_folders) . ')' . ' AND (t.ThemeId = ' . $theme_id . ')', $design_sql); $fields['Template']['options_sql'] = $design_sql; $this->Application->setUnitOption($event->Prefix, 'Fields', $fields); if ($this->Application->IsAdmin()) { // don't sort by Front-End sorting fields $config_mapping = $this->Application->getUnitOption($event->Prefix, 'ConfigMapping'); $remove_keys = Array ('DefaultSorting1Field', 'DefaultSorting2Field', 'DefaultSorting1Dir', 'DefaultSorting2Dir'); foreach ($remove_keys as $remove_key) { unset($config_mapping[$remove_key]); } $this->Application->setUnitOption($event->Prefix, 'ConfigMapping', $config_mapping); } else { // sort by parent path on Front-End only $list_sortings = $this->Application->getUnitOption($event->Prefix, 'ListSortings'); $list_sortings['']['ForcedSorting'] = Array ("CurrentSort" => 'asc'); $this->Application->setUnitOption($event->Prefix, 'ListSortings', $list_sortings); } // add grids for advanced view (with primary category column) $grids = $this->Application->getUnitOption($this->Prefix, 'Grids'); $process_grids = Array ('Default', 'Radio'); foreach ($process_grids as $process_grid) { $grid_data = $grids[$process_grid]; $grid_data['Fields']['CachedNavbar'] = Array ('title' => 'la_col_Path', 'data_block' => 'grid_parent_category_td', 'filter_block' => 'grid_like_filter'); $grids[$process_grid . 'ShowAll'] = $grid_data; } $this->Application->setUnitOption($this->Prefix, 'Grids', $grids); } /** * Removes this item and it's children (recursive) from structure dropdown * * @param kEvent $event */ function OnAfterItemLoad(&$event) { parent::OnAfterItemLoad($event); if (!$this->Application->IsAdmin()) { return ; } $object =& $event->getObject(); // remove this category & it's children from dropdown $sql = 'SELECT '.$object->IDField.' FROM '.$this->Application->getUnitOption($event->Prefix, 'TableName').' WHERE ParentPath LIKE "'.$object->GetDBField('ParentPath').'%"'; $remove_categories = $this->Conn->GetCol($sql); $field_options = $object->GetFieldOptions('ParentId'); foreach ($remove_categories as $remove_category) { unset($field_options['options'][$remove_category]); } $object->SetFieldOptions('ParentId', $field_options); $priority_helper =& $this->Application->recallObject('PriorityHelper'); /* @var $priority_helper kPriorityHelper */ $priority_helper->preparePriorities($event, false, 'ParentId = '.$object->GetDBField('ParentId')); // storing prioriry right after load for comparing when updating $object->SetDBField('OldPriority', $object->GetDBField('Priority')); } /** * Builds list * * @param kEvent $event * @access protected */ function OnListBuild(&$event) { parent::OnListBuild($event); $priority_helper =& $this->Application->recallObject('PriorityHelper'); /* @var $priority_helper kPriorityHelper */ $priority_helper->preparePriorities($event, false, 'ParentId = '.$this->Application->GetVar('m_cat_id')); } /** * Enter description here... * * @param kEvent $event */ function OnAfterRebuildThemes(&$event) { $sql = 'SELECT t.ThemeId, CONCAT( tf.FilePath, \'/\', tf.FileName ) AS Path, tf.FileMetaInfo FROM '.TABLE_PREFIX.'ThemeFiles AS tf LEFT JOIN '.TABLE_PREFIX.'Theme AS t ON t.ThemeId = tf.ThemeId WHERE t.Enabled = 1 AND tf.FileType = 1 AND ( SELECT COUNT(CategoryId) FROM ' . TABLE_PREFIX . 'Category WHERE CONCAT(\'/\', ' . TABLE_PREFIX . 'Category.Template, \'.tpl\') = CONCAT( tf.FilePath, \'/\', tf.FileName ) ) = 0 '; $files = $this->Conn->Query($sql, 'Path'); if (!$files) { // all possible pages are already created return ; } set_time_limit(0); ini_set('memory_limit', -1); $dummy =& $this->Application->recallObject($event->Prefix . '.-dummy', null, Array ('skip_autoload' => true)); /* @var $dummy kDBItem */ $error_count = 0; foreach ($files as $a_file => $file_info) { $status = $this->_prepareAutoPage($dummy, $a_file, $file_info['ThemeId'], SMS_MODE_FORCE, unserialize($file_info['FileMetaInfo'])); // create system page if (!$status) { $error_count++; } } if ($this->Application->ConfigValue('QuickCategoryPermissionRebuild')) { $updater =& $this->Application->recallObject('kPermCacheUpdater'); /* @var $updater kPermCacheUpdater */ $updater->OneStepRun(); } $event->CallSubEvent('OnResetMenuCache'); if ($error_count) { // allow user to review error after structure page creation $event->MasterEvent->redirect = false; } } /** * Processes OnMassMoveUp, OnMassMoveDown events * * @param kEvent $event */ function OnChangePriority(&$event) { $object =& $event->getObject( Array('skip_autoload' => true) ); $ids = $this->StoreSelectedIDs($event); if ($ids) { $id_field = $this->Application->getUnitOption($event->Prefix, 'IDField'); $table_name = $this->Application->getUnitOption($event->Prefix, 'TableName'); $parent_id = $this->Application->GetVar('m_cat_id'); $sql = 'SELECT Priority, '.$id_field.' FROM '.$table_name.' WHERE '.$id_field.' IN ('.implode(',', $ids).')'; $priorities = $this->Conn->GetCol($sql, $id_field); $priority_helper =& $this->Application->recallObject('PriorityHelper'); /* @var $priority_helper kPriorityHelper */ foreach ($ids as $id) { $new_priority = $priorities[$id] + ($event->Name == 'OnMassMoveUp' ? +1 : -1); $changes = Array ( $id => Array ('old' => $priorities[$id], 'new' => $new_priority, 'parent' => $parent_id), ); $sql = 'UPDATE '.$table_name.' SET Priority = '.$new_priority.' WHERE '.$id_field.' = '.$id; $this->Conn->Query($sql); $priority_helper->updatePriorities($event, $changes, Array ($id => $id)); } } $this->clearSelectedIDs($event); $this->Application->StoreVar('RefreshStructureTree', 1); } /** * Completely recalculates priorities in current category * * @param kEvent $event */ function OnRecalculatePriorities(&$event) { $priority_helper =& $this->Application->recallObject('PriorityHelper'); /* @var $priority_helper kPriorityHelper */ $parent_id = $this->Application->GetVar('m_cat_id'); $priority_helper->recalculatePriorities($event, 'ParentId = ' . $parent_id); } /** * Update Preview Block for FCKEditor * * @param kEvent $event */ function OnUpdatePreviewBlock(&$event) { $event->status = erSTOP; $string = unhtmlentities($this->Application->GetVar('preview_content')); $category_helper =& $this->Application->recallObject('CategoryHelper'); /* @var $category_helper CategoryHelper */ $string = $category_helper->replacePageIds($string); $this->Application->StoreVar('_editor_preview_content_', $string); } } ?> \ No newline at end of file Index: branches/RC/core/units/structure/structure_config.php =================================================================== --- branches/RC/core/units/structure/structure_config.php (revision 11896) +++ branches/RC/core/units/structure/structure_config.php (revision 11897) @@ -1,232 +1,232 @@ <?php /** * @version $Id$ * @package In-Portal * @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved. * @license GNU/GPL * In-Portal is Open Source software. * This means that this software may have been modified pursuant * the GNU General Public License, and as distributed it includes * or is derivative of works licensed under the GNU General Public License * or other free or open source software licenses. * See http://www.in-portal.net/license/ for copyright notices and details. */ $config = Array ( 'Prefix' => 'st', 'ItemClass' => Array('class'=>'CategoriesItem','file'=>'structure_item.php', 'build_event'=>'OnItemBuild'), 'ListClass' => Array('class'=>'kDBList','file'=>'','build_event'=>'OnListBuild'), 'EventHandlerClass' => Array('class'=>'CategoriesEventHandler','file'=>'structure_eh.php', 'build_event'=>'OnBuild'), 'TagProcessorClass' => Array('class'=>'CategoriesTagProcessor','file'=>'structure_tp.php', 'build_event'=>'OnBuild'), 'AutoLoad' => true, 'QueryString' => Array( 1 => 'id', 2 => 'page', 3 => 'event', 4 => 'mode', ), 'ConfigPriority' => 0, 'Hooks' => Array( Array ( 'Mode' => hBEFORE, 'Conditional' => false, 'HookToPrefix' => '', 'HookToSpecial' => '*', 'HookToEvent' => Array('OnAfterConfigRead'), 'DoPrefix' => 'cdata', 'DoSpecial' => '*', 'DoEvent' => 'OnDefineCustomFields', ), ), 'IDField' => 'CategoryId', 'StatusField' => Array('IsMenu'), 'TitleField' => 'Name', // field, used in bluebar when editing existing item 'TableName' => TABLE_PREFIX.'Category', 'TitlePresets' => Array( 'default' => Array( 'new_status_labels' => Array('st'=>'!la_title_Adding_Category!'), 'edit_status_labels' => Array('st'=>'!la_title_Editing_Category!'), 'new_titlefield' => Array('st'=>'!la_title_New_Category!'), ), 'structure_list' => Array( 'prefixes' => Array('st_List', 'st.current'), 'format' => "!la_title_Structure! - '#st.current_Name#'" ), 'structure_edit' => Array( 'prefixes' => Array('st'), 'format' => "#st_status# '#st_titlefield#'", ), 'all_pages_list' => Array('prefixes' => Array('st.all_List'), 'format' => "!la_title_AllPages!"), 'edit_content' => array('format' => '!la_EditingContent!'), /* 'categories_edit' => Array('prefixes' => Array('c'), 'format' => "#c_status# '#c_titlefield#' - !la_title_General!"),*/ ), 'PermItemPrefix' => 'CATEGORY', 'PermSection' => Array('main' => 'CATEGORY:in-portal:structure', 'email' => 'in-portal:configemail'), 'ListSQLs' => Array( ''=> ' SELECT %1$s.* %2$s FROM %1$s LEFT JOIN '.TABLE_PREFIX.'PermCache ON '.TABLE_PREFIX.'PermCache.CategoryId = %1$s.CategoryId'), 'ItemSQLs' => Array( ''=> ' SELECT %1$s.* %2$s FROM %1$s LEFT JOIN '.TABLE_PREFIX.'PermCache ON '.TABLE_PREFIX.'PermCache.CategoryId = %1$s.CategoryId'), 'SubItems' => Array('content'), 'ListSortings' => Array( '' => Array( 'ForcedSorting' => Array('Priority' => 'desc'), 'Sorting' => Array('Name' => 'asc'), ) ), 'CalculatedFields' => Array( '' => Array( 'CurrentSort' => "REPLACE(ParentPath, CONCAT('|', ".'%1$s'.".CategoryId, '|'), '')", ) ), 'Fields' => Array ( 'CategoryId' => Array('type' => 'int', 'not_null' => 1,'default' => 0), 'Type' => Array('type' => 'int','not_null' => 1,'default' => 0), 'SymLinkCategoryId' => Array ('type' => 'int', 'default' => NULL), 'ParentId' => Array('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (), 'not_null' => 1,'default' => 0, 'required'=>1), - 'Name' => Array('type' => 'string', 'formatter' => 'kMultiLanguage', 'format'=>'no_default', 'not_null' => 1, 'required' => 1, 'default' => ''), + 'Name' => Array('type' => 'string', 'formatter' => 'kMultiLanguage', 'not_null' => 1, 'required' => 1, 'default' => ''), 'Filename' => Array('type' => 'string', 'not_null' => 1, 'default' => '', 'required' => 1), 'AutomaticFilename' => Array('type' => 'int', 'not_null' => 1, 'default' => 1), - 'Description' => Array('type' => 'string', 'formatter' => 'kMultiLanguage', 'format'=>'no_default', 'default' => null), + 'Description' => Array('type' => 'string', 'formatter' => 'kMultiLanguage', 'default' => null), 'CreatedOn' => Array('type' => 'int', 'formatter' => 'kDateFormatter', 'default'=>'#NOW#', 'required' => 1, 'not_null' => 1), 'EditorsPick' => Array('type' => 'int', 'not_null' => 1, 'default' => 0), 'Status' => Array('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_Active', 2 => 'la_Pending', 0 => 'la_Disabled' ), 'use_phrases' => 1, 'not_null' => 1,'default' => 1), 'Priority' => Array('type' => 'int', 'not_null' => 1, 'formatter' => 'kOptionsFormatter', 'options' => array(), 'required' => 1, 'default' => 0), 'MetaKeywords' => Array('type' => 'string', 'default' => null), 'CachedDescendantCatsQty' => Array('type' => 'int', 'default' => 0), 'CachedNavbar' => Array('type' => 'string', 'formatter' => 'kMultiLanguage', 'default' => null), 'CreatedById' => Array('type' => 'int', 'formatter' => 'kLEFTFormatter', 'options' => Array(-1 => 'root', -2 => 'Guest'),'left_sql'=>'SELECT %s FROM '.TABLE_PREFIX.'PortalUser WHERE `%s` = \'%s\'', 'left_key_field' => 'PortalUserId', 'left_title_field' => 'Login', 'not_null' => 1,'default' => 0), 'ResourceId' => Array('type' => 'int', 'default' => null), 'ParentPath' => Array('type' => 'string', 'default' => null), 'TreeLeft' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), 'TreeRight' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), 'NamedParentPath' => Array('type' => 'string', 'default' => null), 'MetaDescription' => Array('type' => 'string', 'default' => null), 'HotItem' => Array('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (2 => 'la_Auto', 1 => 'la_Always', 0 => 'la_Never'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 2), 'NewItem' => Array('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (2 => 'la_Auto', 1 => 'la_Always', 0 => 'la_Never'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 2), 'PopItem' => Array('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (2 => 'la_Auto', 1 => 'la_Always', 0 => 'la_Never'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 2), 'Modified' => Array('type' => 'int', 'formatter' => 'kDateFormatter', 'not_null' => 1,'default' => '#NOW#'), 'ModifiedById' => Array('type' => 'int', 'formatter' => 'kLEFTFormatter', 'options' => Array(-1 => 'root', -2 => 'Guest'),'left_sql'=>'SELECT %s FROM '.TABLE_PREFIX.'PortalUser WHERE `%s` = \'%s\'', 'left_key_field' => 'PortalUserId', 'left_title_field' => 'Login', 'not_null' => 1,'default' => 0), 'CachedTemplate' => Array('type' => 'string', 'not_null' => 1, 'default' => ''), // fields from Pages 'Template' => Array ( 'type' => 'string', 'formatter' => 'kOptionsFormatter', 'options_sql' => ' SELECT CONCAT(tf.Description, " (", TRIM(TRAILING ".des" FROM TRIM(TRAILING ".tpl" FROM FileName) ), ")") AS Title, CONCAT(FilePath, "/", TRIM(TRAILING ".tpl" FROM FileName)) AS Value FROM ' . TABLE_PREFIX . 'ThemeFiles AS tf LEFT JOIN ' . TABLE_PREFIX . 'Theme AS t ON t.ThemeId = tf.ThemeId WHERE (t.Enabled = 1) AND (tf.FileName NOT LIKE "%%.elm.tpl") AND (tf.FileName NOT LIKE "%%.des.tpl") AND (tf.FilePath = "/designs")', 'option_key_field' => 'Value', 'option_title_field' => 'Title', /*'required' => 1,*/ 'default' => null ), 'UseExternalUrl' => Array ( 'type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (0 => 'la_No', 1 => 'la_Yes'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 0 ), 'ExternalUrl' => Array ('type' => 'string', 'max_len' => 255, 'not_null' => 1, 'default' => ''), 'UseMenuIconUrl' => Array ( 'type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (0 => 'la_No', 1 => 'la_Yes'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 0 ), 'MenuIconUrl' => Array ('type' => 'string', 'max_len' => 255, 'not_null' => 1, 'default' => ''), - 'Title' => Array('type' => 'string', 'formatter' => 'kMultiLanguage', 'format'=>'no_default', 'default' => '', 'not_null'=>1), - 'MenuTitle' => Array('type' => 'string', 'formatter' => 'kMultiLanguage', 'format'=>'no_default', 'not_null' => 1, 'default' => ''), + 'Title' => Array('type' => 'string', 'formatter' => 'kMultiLanguage', 'default' => '', 'not_null'=>1), + 'MenuTitle' => Array('type' => 'string', 'formatter' => 'kMultiLanguage', 'not_null' => 1, 'default' => ''), 'MetaTitle' => Array('type' => 'string', 'default' => null), 'IndexTools' => Array('type' => 'string','default' => null), 'IsIndex' => Array( 'type' => 'int','not_null' => 1, 'default' => 0, 'formatter' => 'kOptionsFormatter', 'options' => Array (0 => 'la_Regular', 1 => 'la_CategoryIndex', 2=>'la_Container'), 'use_phrases' => 1, ), 'IsMenu' => Array('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_Show', 0 => 'la_Hide'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 1), 'IsSystem' => Array('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => Array (1 => 'la_System', 0 => 'la_Regular'), 'use_phrases' => 1, 'not_null' => 1, 'default' => 0), 'FormId' => Array('type' => 'int', 'formatter' => 'kOptionsFormatter', 'options' => array('' => ''), 'options_sql' => 'SELECT Title, FormId FROM '.TABLE_PREFIX.'Forms ORDER BY Title', 'option_key_field' => 'FormId', 'option_title_field' => 'Title', 'default' => 0), 'FormSubmittedTemplate' => Array('type' => 'string', 'default' => null), 'Translated' => Array ('type' => 'int', 'formatter' => 'kMultiLanguage', 'not_null' => 1, 'default' => 0, 'db_type' => 'tinyint', 'index_type' => 'int'), 'FriendlyURL' => Array ('type' => 'string', 'not_null' => 1, 'default' => ''), 'ThemeId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), ), 'VirtualFields' => Array( 'CurrentSort' => Array('type' => 'string', 'default' => ''), 'IsNew' => Array('type' => 'int', 'default' => 0), 'OldPriority' => Array('type' => 'int', 'default' => 0), ), 'Grids' => Array( 'Default' => Array( 'Icons' => Array(1 => 'icon16_folder.gif', 0 => 'icon16_folder-red.gif'), 'Fields' => Array( 'CategoryId' => Array( 'title'=>'la_col_Id', 'data_block' => 'grid_checkbox_td', 'filter_block' => 'grid_range_filter', 'filter_width' => '20' ), 'Name' => Array( 'title'=>'la_col_PageTitle', 'data_block' => 'page_browse_td', 'filter_block' => 'grid_like_filter'), 'Modified' => Array( 'title'=>'la_col_Modified', 'filter_block' => 'grid_date_range_filter' ), 'Template' => Array( 'title'=>'la_col_TemplateType', 'filter_block' => 'grid_options_filter' ), 'IsMenu' => Array( 'title'=>'la_col_Visible', 'filter_block' => 'grid_options_filter' ), 'Path' => Array( 'title'=>'la_col_Path', 'data_block' => 'page_entercat_td', 'filter_block' => 'grid_like_filter' ), 'IsSystem' => Array( 'title'=>'la_col_System', 'filter_block' => 'grid_options_filter', 'use_phrases'=>1 ), ), ), 'Radio' => Array( 'Icons' => Array(1 => 'icon16_folder.gif', 0 => 'icon16_folder-red.gif'), 'Selector' => 'radio', 'Fields' => Array( 'CategoryId' => Array( 'title'=>'la_col_Id', 'data_block' => 'grid_checkbox_td', 'filter_block' => 'grid_range_filter', 'filter_width' => '20' ), 'Name' => Array( 'title'=>'la_col_PageTitle', 'data_block' => 'page_browse_td', 'filter_block' => 'grid_like_filter'), 'Modified' => Array( 'title'=>'la_col_Modified', 'filter_block' => 'grid_date_range_filter' ), 'Template' => Array( 'title'=>'la_col_TemplateType', 'filter_block' => 'grid_options_filter' ), 'IsMenu' => Array( 'title'=>'la_col_Visible', 'filter_block' => 'grid_options_filter' ), 'Path' => Array( 'title'=>'la_col_Path', 'data_block' => 'page_entercat_td', 'filter_block' => 'grid_like_filter' ), 'IsSystem' => Array( 'title'=>'la_col_System', 'filter_block' => 'grid_options_filter', 'use_phrases'=>1 ), ), ), 'AllPages' => Array( 'Icons' => Array(1 => 'icon16_folder.gif', 0 => 'icon16_folder-red.gif'), 'Fields' => Array( 'CategoryId' => Array( 'title'=>'la_col_Id', 'data_block' => 'grid_checkbox_td', 'filter_block' => 'grid_range_filter', 'filter_width' => '20' ), 'Name' => Array( 'title'=>'la_col_PageTitle', 'data_block' => 'page_browse_td', 'filter_block' => 'grid_like_filter' ), 'Path' => Array( 'title'=>'la_col_Path', 'data_block'=>'page_path_td', 'sort_field' => 'CachedNavbar', 'filter_block' => 'grid_like_filter' ), 'Modified' => Array( 'title'=>'la_col_Modified', 'filter_block' => 'grid_date_range_filter' ), 'Template' => Array( 'title'=>'la_col_TemplateType', 'filter_block' => 'grid_options_filter', 'hidden' => true ), 'IsMenu' => Array( 'title'=>'la_col_Visible', 'filter_block' => 'grid_options_filter' ), 'IsSystem' => Array( 'title'=>'la_col_System', 'filter_block' => 'grid_options_filter', 'use_phrases'=>1 ), ), ), ), 'ConfigMapping' => Array( 'PerPage' => 'Perpage_Category', 'ShortListPerPage' => 'Perpage_Category_Short', 'DefaultSorting1Field' => 'Category_Sortfield', 'DefaultSorting2Field' => 'Category_Sortfield2', 'DefaultSorting1Dir' => 'Category_Sortorder', 'DefaultSorting2Dir' => 'Category_Sortorder2', ), ); \ No newline at end of file Index: branches/RC/core/units/content/content_config.php =================================================================== --- branches/RC/core/units/content/content_config.php (revision 11896) +++ branches/RC/core/units/content/content_config.php (revision 11897) @@ -1,65 +1,65 @@ <?php /** * @version $Id$ * @package In-Portal * @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved. * @license GNU/GPL * In-Portal is Open Source software. * This means that this software may have been modified pursuant * the GNU General Public License, and as distributed it includes * or is derivative of works licensed under the GNU General Public License * or other free or open source software licenses. * See http://www.in-portal.net/license/ for copyright notices and details. */ $config = Array ( 'Prefix' => 'content', 'ItemClass' => Array ('class' => 'kDBItem', 'file' => '', 'build_event' => 'OnItemBuild'), 'ListClass' => Array ('class' => 'kDBList', 'file' => '', 'build_event' => 'OnListBuild'), 'EventHandlerClass' => Array ('class' => 'ContentEventHandler', 'file' => 'content_eh.php', 'build_event' => 'OnBuild'), 'TagProcessorClass' => Array ('class' => 'kDBTagProcessor', 'file' => '', 'build_event' => 'OnBuild'), 'AutoLoad' => true, 'QueryString' => Array ( 1 => 'id', 2 => 'Page', 3 => 'event', 4 => 'mode', ), 'IDField' => 'PageContentId', 'ParentTableKey' => 'CategoryId', // linked field in master table 'ForeignKey' => 'PageId', // linked field in subtable 'ParentPrefix' => 'c', 'AutoDelete' => true, 'AutoClone' => true, 'TitleField' => 'ContentNum', // field, used in bluebar when editing existing item 'ViewMenuPhrase' => 'la_text_Pages', 'TitlePhrase' => 'la_text_PageContent', 'TitlePresets' => Array ( 'default' => Array ( 'new_status_labels' => Array ('content' => '!la_title_Adding_Content!'), 'edit_status_labels' => Array ('content' => '!la_title_Editing_Content!'), ), 'content_edit' => Array ('prefixes' => Array ('content'), 'format' => '#content_status# - !la_title_General!'), ), 'TableName' => TABLE_PREFIX . 'PageContent', 'ListSQLs' => Array ('' => 'SELECT * FROM %s'), 'ListSortings' => Array ( '' => Array ( 'Sorting' => Array ('ContentNum' => 'asc'), ) ), 'Fields' => Array ( 'PageContentId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), 'ContentNum' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), 'PageId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), - 'Content' => Array ('type' => 'string', 'formatter' => 'kMultiLanguage', 'format' => 'no_default', 'using_fck' => 1, 'default' => ''), + 'Content' => Array ('type' => 'string', 'formatter' => 'kMultiLanguage', 'using_fck' => 1, 'default' => ''), 'Translated' => Array ('type' => 'int', 'formatter' => 'kMultiLanguage', 'not_null' => 1, 'default' => 0, 'db_type' => 'tinyint', 'index_type' => 'int'), ), ); Index: branches/RC/core/admin_templates/categories/edit_content.tpl =================================================================== --- branches/RC/core/admin_templates/categories/edit_content.tpl (revision 11896) +++ branches/RC/core/admin_templates/categories/edit_content.tpl (revision 11897) @@ -1,70 +1,70 @@ <inp2:adm_SetPopupSize width="700" height="600"/> <inp2:m_include t="incs/header"/> <inp2:m_RenderElement name="combined_header" prefix="c" section="in-portal:browse" title_preset="edit_content"/> <!-- ToolBar --> <table class="toolbar" height="30" cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td> <script type="text/javascript"> a_toolbar = new ToolBar(); a_toolbar.AddButton( new ToolBarButton( 'select', '<inp2:m_phrase label="la_ToolTip_Save" escape="1"/>', function() { submit_event('content','<inp2:content_SaveEvent/>'); } ) ); a_toolbar.AddButton( new ToolBarButton( 'cancel', '<inp2:m_phrase label="la_ToolTip_Cancel" escape="1"/>', function() { cancel_edit('content','OnCancelEdit','<inp2:content_SaveEvent/>','<inp2:m_Phrase label="la_FormCancelConfirmation" escape="1"/>'); } ) ); a_toolbar.AddButton( new ToolBarButton( 'reset_edit', '<inp2:m_phrase label="la_ToolTip_Reset" escape="1"/>', function() { reset_form('content', 'OnReset', '<inp2:m_Phrase label="la_FormResetConfirmation" escape="1"/>'); } ) ); a_toolbar.Render(); </script> </td> <inp2:m_RenderElement name="ml_selector" prefix="content"/> </tr> </tbody> </table> <div id="scroll_container"> <table class="edit-form" style="border-collapse: separate;"> <tr> <td style="padding: 0px;"> - <inp2:content_FCKEditor field="Content" width="100%" height="100" late_load="1"/> + <inp2:content_FCKEditor field="Content" width="100%" height="100" format="no_default" late_load="1"/> <script type="text/javascript"> Form.addControl('<inp2:content_InputName field="Content"/>___Frame'); </script> </td> </tr> </table> </div> <input type="hidden" name="c_id" value="<inp2:m_Get name='c_id'/>"/> <inp2:m_include t="incs/footer"/> \ No newline at end of file