diff --git a/root/adm/style/portal/acp_portal_custom.html b/root/adm/style/portal/acp_portal_custom.html
new file mode 100644
index 00000000..c164954c
--- /dev/null
+++ b/root/adm/style/portal/acp_portal_custom.html
@@ -0,0 +1,645 @@
+
+
+
+
+
{L_TITLE}
+
+{L_TITLE_EXPLAIN}
+
+
+
+
{L_WARNING}
+
{ERROR_MSG}
+
+
+
+
+
\ No newline at end of file
diff --git a/root/language/en/mods/portal/portal_custom_module.php b/root/language/en/mods/portal/portal_custom_module.php
new file mode 100644
index 00000000..644d7c77
--- /dev/null
+++ b/root/language/en/mods/portal/portal_custom_module.php
@@ -0,0 +1,49 @@
+ 'Custom Block',
+
+ // ACP
+ 'ACP_PORTAL_CUSTOM_SETTINGS' => 'Custom Block Settings',
+ 'ACP_PORTAL_CUSTOM_SETTINGS_EXP' => 'Here you can edit your custom block',
+ 'ACP_PORTAL_CUSTOM_CODE_SHORT' => 'The code you entered is not long enough.',
+ 'ACP_PORTAL_CUSTOM_PREVIEW' => 'Preview',
+ 'ACP_PORTAL_CUSTOM_CODE' => 'Custom Block Code',
+ 'ACP_PORTAL_CUSTOM_CODE_EXP' => 'Change the code for the small custom block (HTML or BBCode) here.',
+ 'ACP_PORTAL_CUSTOM_PERMISSION' => 'Custom Block permissions',
+ 'ACP_PORTAL_CUSTOM_PERMISSION_EXP' => 'Select the groups that should be able to view the custom block. If you want all users to be able to view the custom block, don´t select anything.
Select/Deselect multiple groups by holding CTRL and clicking.',
+ 'ACP_PORTAL_CUSTOM_BBCODE' => 'Activate BBCode for the custom block',
+ 'ACP_PORTAL_CUSTOM_BBCODE_EXP' => 'BBCode could be used in this box. If BBCode is not activated, HTML will be parsed.',
+));
+
+?>
\ No newline at end of file
diff --git a/root/portal.php b/root/portal.php
index 21b71c8d..d2865f85 100644
--- a/root/portal.php
+++ b/root/portal.php
@@ -86,10 +86,23 @@ while ($row = $db->sql_fetchrow($result))
continue;
}
- $template->assign_block_vars('modules_' . column_num_string($row['module_column']), array(
- 'TEMPLATE_FILE' => 'portal/modules/' . $template_module,
- 'IMAGE_SRC' => $phpbb_root_path . 'styles/' . $user->theme['theme_path'] . '/theme/images/portal/' . $row['module_image_src'],
- ));
+ // Custom Blocks that have been defined in the ACP will return an array instead of just the name of the template file
+ if(is_array($template_module))
+ {
+ $template->assign_block_vars('modules_' . column_num_string($row['module_column']), array(
+ 'TEMPLATE_FILE' => 'portal/modules/' . $template_module['template'],
+ 'IMAGE_SRC' => $phpbb_root_path . 'styles/' . $user->theme['theme_path'] . '/theme/images/portal/' . $template_module['image_src'],
+ 'TITLE' => $template_module['title'],
+ 'CODE' => $template_module['code'],
+ ));
+ }
+ else
+ {
+ $template->assign_block_vars('modules_' . column_num_string($row['module_column']), array(
+ 'TEMPLATE_FILE' => 'portal/modules/' . $template_module,
+ 'IMAGE_SRC' => $phpbb_root_path . 'styles/' . $user->theme['theme_path'] . '/theme/images/portal/' . $row['module_image_src'],
+ ));
+ }
unset($template_module);
}
$db->sql_freeresult($result);
diff --git a/root/portal/modules/portal_custom.php b/root/portal/modules/portal_custom.php
new file mode 100644
index 00000000..5b36081b
--- /dev/null
+++ b/root/portal/modules/portal_custom.php
@@ -0,0 +1,351 @@
+lang}/mods/portal/"
+ */
+ var $language = 'portal_custom_module';
+
+ /**
+ * custom acp template
+ * file must be in "adm/style/portal/"
+ */
+ var $custom_acp_tpl = 'acp_portal_custom';
+
+ function get_template_center($module_id)
+ {
+ global $config, $template, $portal_config, $user;
+
+ /*
+ * Run generate_text_for_display if the user uses BBCode for designing his custom block
+ * HTML won't be parsed if the user chooses to use BBCodes in the ACP
+ * If BBCodes are turned off, the custom Block code will be directly assigned and HTML will be parsed
+ */
+ if ($config['board3_custom_' . $module_id . '_bbcode'])
+ {
+ // Generate text for display and assign template vars
+ $uid = $config['board3_custom_' . $module_id . '_uid'];
+ $bitfield = $config['board3_custom_' . $module_id . '_bitfield'];
+ $bbcode_options = OPTION_FLAG_BBCODE + OPTION_FLAG_SMILIES + OPTION_FLAG_LINKS;
+ $assign_code = generate_text_for_display($portal_config['board3_custom_' . $module_id . '_code'], $uid, $bitfield, $bbcode_options);
+ }
+ else
+ {
+ $assign_code = htmlspecialchars_decode($portal_config['board3_custom_' . $module_id . '_code'], ENT_QUOTES);
+ }
+
+ $title = (!empty($config['board3_custom_' . $module_id . '_title'])) ? ((isset($user->lang[$config['board3_custom_' . $module_id . '_title']])) ? $user->lang[$config['board3_custom_' . $module_id . '_title']] : $config['board3_custom_' . $module_id . '_title']) : $user->lang[$this->name];
+
+ return array(
+ 'template' => 'custom_center.html',
+ 'title' => $title,
+ 'code' => $assign_code,
+ 'image_src' => '', // no image for center blocks
+ );
+ }
+
+ function get_template_side($module_id)
+ {
+ global $config, $template, $portal_config, $user;
+
+ /*
+ * Run generate_text_for_display if the user uses BBCode for designing his custom block
+ * HTML won't be parsed if the user chooses to use BBCodes in the ACP
+ * If BBCodes are turned off, the custom Block code will be directly assigned and HTML will be parsed
+ */
+ if ($config['board3_custom_' . $module_id . '_bbcode'])
+ {
+ echo 'shouldn´t be in here';
+ // Generate text for display and assign template vars
+ $uid = $config['board3_custom_' . $module_id . '_uid'];
+ $bitfield = $config['board3_custom_' . $module_id . '_bitfield'];
+ $bbcode_options = OPTION_FLAG_BBCODE + OPTION_FLAG_SMILIES + OPTION_FLAG_LINKS;
+ $assign_code = generate_text_for_display($portal_config['board3_custom_' . $module_id . '_code'], $uid, $bitfield, $bbcode_options);
+ }
+ else
+ {
+ $assign_code = htmlspecialchars_decode($portal_config['board3_custom_' . $module_id . '_code'], ENT_QUOTES);
+ }
+
+ $title = (!empty($config['board3_custom_' . $module_id . '_title'])) ? ((isset($user->lang[$config['board3_custom_' . $module_id . '_title']])) ? $user->lang[$config['board3_custom_' . $module_id . '_title']] : $config['board3_custom_' . $module_id . '_title']) : $user->lang[$this->name];
+
+ return array(
+ 'template' => 'custom_side.html',
+ 'title' => $title,
+ 'code' => $assign_code,
+ 'image_src' => (!empty($config['board3_custom_' . $module_id . '_image_src'])) ? $config['board3_custom_' . $module_id . '_image_src'] : $this->image_src,
+ );
+ }
+
+ function get_template_acp($module_id)
+ {
+ return array(
+ 'title' => 'PORTAL_CUSTOM',
+ 'vars' => array(
+ 'legend1' => 'PORTAL_CUSTOM',
+ 'board3_custom_' . $module_id . '_code' => array('lang' => 'PORTAL_CUSTOM', 'validate' => 'string', 'type' => 'custom', 'method' => 'manage_custom', 'submit' => 'update_custom', 'explain' => true),
+ ),
+ );
+ }
+
+ /**
+ * API functions
+ */
+ function install($module_id)
+ {
+ set_portal_config('board3_custom_' . $module_id . '_code', '');
+ set_config('board3_custom_' . $module_id . '_code', '');
+ set_config('board3_custom_' . $module_id . '_bbcode', 1);
+ set_config('board3_custom_' . $module_id . '_title', '');
+ set_config('board3_custom_' . $module_id . '_image_src', '');
+ set_config('board3_custom_' . $module_id . '_uid', '');
+ set_config('board3_custom_' . $module_id . '_bitfield', '');
+ set_config('board3_custom_' . $module_id . '_permission', '');
+ return true;
+ }
+
+ function uninstall($module_id)
+ {
+ global $db;
+
+ $del_config = array(
+ 'board3_custom_' . $module_id . '_code',
+ );
+ $sql = 'DELETE FROM ' . PORTAL_CONFIG_TABLE . '
+ WHERE ' . $db->sql_in_set('config_name', $del_config);
+
+ $check = $db->sql_query($sql);
+
+ $del_config = array(
+ 'board3_custom_' . $module_id . '_bbcode',
+ 'board3_custom_' . $module_id . '_title',
+ 'board3_custom_' . $module_id . '_image_src',
+ 'board3_custom_' . $module_id . '_uid',
+ 'board3_custom_' . $module_id . '_bitfield',
+ 'board3_custom_' . $module_id . '_permission',
+ );
+ $sql = 'DELETE FROM ' . CONFIG_TABLE . '
+ WHERE ' . $db->sql_in_set('config_name', $del_config);
+ return ((!$check) ? $check : $db->sql_query($sql)); // if something went wrong, make sure we are aware of the first query
+ }
+
+ function manage_custom($value, $key, $module_id)
+ {
+ global $db, $portal_config, $config, $template, $user, $phpEx, $phpbb_admin_path, $phpbb_root_path;
+
+ $action = (isset($_POST['reset'])) ? 'reset' : '';
+ $action = (isset($_POST['submit'])) ? 'save' : $action;
+ $action = (isset($_POST['preview'])) ? 'preview' : $action;
+
+ $portal_config = obtain_portal_config();
+
+ $u_action = append_sid($phpbb_admin_path . 'index.' . $phpEx, 'i=portal&mode=config&module_id=' . $module_id);
+
+ switch($action)
+ {
+ // Save changes
+ case 'save':
+ if (!check_form_key('acp_portal'))
+ {
+ trigger_error($user->lang['FORM_INVALID']. adm_back_link($u_action), E_USER_WARNING);
+ }
+
+ $custom_code = utf8_normalize_nfc(request_var('custom_code', '', true));
+ $custom_bbcode = request_var('custom_use_bbcode', 1); // default to BBCode
+ $custom_permission = request_var('permission-setting', array(0 => ''));
+ $custom_title = utf8_normalize_nfc(request_var('module_name', ''));
+ $custom_image_src = utf8_normalize_nfc(request_var('module_image', ''));
+ $groups_ary = array();
+ $uid = $bitfield = $flags = '';
+ $options = 7;
+ if($custom_bbcode)
+ {
+ generate_text_for_storage($custom_code, $uid, $bitfield, $flags, true, true, true);
+ }
+
+
+ // first check for obvious errors, we don't want to waste server resources
+ if(empty($custom_code))
+ {
+ trigger_error($user->lang['ACP_PORTAL_CUSTOM_CODE_SHORT']. adm_back_link($u_action), E_USER_WARNING);
+ }
+
+ // get groups and check if the selected groups actually exist
+ $sql = 'SELECT group_id
+ FROM ' . GROUPS_TABLE . '
+ ORDER BY group_id ASC';
+ $result = $db->sql_query($sql);
+ while($row = $db->sql_fetchrow($result))
+ {
+ $groups_ary[] = $row['group_id'];
+ }
+ $db->sql_freeresult($result);
+
+ $custom_permission = array_intersect($custom_permission, $groups_ary);
+ $custom_permission = implode(',', $custom_permission);
+
+ add_log('admin', 'LOG_PORTAL_CONFIG', $user->lang['PORTAL_CUSTOM'] . ' - ' . $config['board3_custom_' . $module_id . '_title']);
+
+ // set_portal_config will take care of escaping the welcome message
+ set_portal_config('board3_custom_' . $module_id . '_code', $custom_code);
+ set_config('board3_custom_' . $module_id . '_bbcode', $custom_bbcode);
+ set_config('board3_custom_' . $module_id . '_title', $custom_title);
+ set_config('board3_custom_' . $module_id . '_image_src', $custom_image_src);
+ set_config('board3_custom_' . $module_id . '_uid', $uid);
+ set_config('board3_custom_' . $module_id . '_bitfield', $bitfield);
+ set_config('board3_custom_' . $module_id . '_permission', $custom_permission);
+
+ trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link(($module_id) ? append_sid("{$phpbb_admin_path}index.$phpEx", 'i=portal&mode=modules') : $u_action));
+
+ break;
+
+ case 'preview':
+ $custom_code = $text = utf8_normalize_nfc(request_var('custom_code', '', true));
+ $custom_bbcode = request_var('custom_use_bbcode', 1); // default to BBCode
+ $custom_permission = request_var('permission-setting', array(0 => ''));
+ $custom_title = utf8_normalize_nfc(request_var('module_name', ''));
+ $custom_image_src = utf8_normalize_nfc(request_var('module_image', ''));
+ $groups_ary = array();
+
+ // first check for obvious errors, we don't want to waste server resources
+ if(empty($custom_code))
+ {
+ trigger_error($user->lang['ACP_PORTAL_CUSTOM_CODE_SHORT']. adm_back_link($u_action), E_USER_WARNING);
+ }
+
+ if (!class_exists('parse_message'))
+ {
+ include($phpbb_root_path . 'includes/message_parser.' . $phpEx);
+ }
+ if($custom_bbcode)
+ {
+ $bbcode_options = OPTION_FLAG_BBCODE + OPTION_FLAG_SMILIES + OPTION_FLAG_LINKS;
+ $uid = (isset($config['board3_custom_' . $module_id . '_uid'])) ? $config['board3_custom_' . $module_id . '_uid'] : '';
+ $bitfield = (isset($config['board3_custom_' . $module_id . '_bitfield'])) ? $config['board3_custom_' . $module_id . '_bitfield'] : '';
+ $options = OPTION_FLAG_BBCODE + OPTION_FLAG_SMILIES + OPTION_FLAG_LINKS;
+ generate_text_for_storage($text, $uid, $bitfield, $options, true, true, true);
+
+ $text = generate_text_for_display($text, $uid, $bitfield, $options);
+ }
+ else
+ {
+ $text = htmlspecialchars_decode($text, ENT_QUOTES);
+ }
+
+ $template->assign_vars(array(
+ 'PREVIEW_TEXT' => $text,
+ 'S_PREVIEW' => true,
+ ));
+
+ // get groups and check if the selected groups actually exist
+ $sql = 'SELECT group_id
+ FROM ' . GROUPS_TABLE . '
+ ORDER BY group_id ASC';
+ $result = $db->sql_query($sql);
+ while($row = $db->sql_fetchrow($result))
+ {
+ $groups_ary[] = $row['group_id'];
+ }
+ $db->sql_freeresult($result);
+
+ $temp_permissions = array_intersect($custom_permission, $groups_ary);
+
+ // Edit or add menu item
+ case 'reset':
+ default:
+ if(!isset($custom_code))
+ {
+ $custom_code = generate_text_for_edit($portal_config['board3_custom_' . $module_id . '_code'], $config['board3_custom_' . $module_id . '_uid'], '');
+ }
+
+ $template->assign_vars(array(
+ 'CUSTOM_CODE' => (is_array($custom_code)) ? $custom_code['text'] : $custom_code,
+ 'CUSTOM_USE_BBCODE' => (isset($custom_bbcode)) ? $custom_bbcode : (($config['board3_custom_' . $module_id . '_bbcode'] != '') ? $config['board3_custom_' . $module_id . '_bbcode'] : true), // BBCodes are selected by default
+ //'U_BACK' => $u_action,
+ 'U_ACTION' => $u_action,
+ 'S_EDIT' => true,
+ 'S_LINKS_ALLOWED' => true,
+ 'S_BBCODE_IMG' => true,
+ 'S_BBCODE_FLASH' => true,
+ 'S_BBCODE_QUOTE' => true,
+ 'S_BBCODE_ALLOWED' => true,
+ 'MAX_FONT_SIZE' => (int) $config['max_post_font_size'],
+ ));
+
+ $groups_ary = (isset($temp_permissions)) ? $temp_permissions : ((isset($config['board3_custom_' . $module_id . '_permission'])) ? explode(',', $config['board3_custom_' . $module_id . '_permission']) : array());
+
+ // get group info from database and assign the block vars
+ $sql = 'SELECT group_id, group_name
+ FROM ' . GROUPS_TABLE . '
+ ORDER BY group_id ASC';
+ $result = $db->sql_query($sql);
+ while($row = $db->sql_fetchrow($result))
+ {
+ $template->assign_block_vars('permission_setting', array(
+ 'SELECTED' => (in_array($row['group_id'], $groups_ary)) ? true : false,
+ 'GROUP_NAME' => (isset($user->lang['G_' . $row['group_name']])) ? $user->lang['G_' . $row['group_name']] : $row['group_name'],
+ 'GROUP_ID' => $row['group_id'],
+ ));
+ }
+ $db->sql_freeresult($result);
+
+ if(!function_exists('display_forums'))
+ {
+ include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
+ }
+
+ // Build custom bbcodes array
+ display_custom_bbcodes();
+ $user->add_lang('posting');
+
+ break;
+ }
+ }
+
+ function update_custom($key, $module_id)
+ {
+ $this->manage_custom('', $key, $module_id);
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/root/styles/prosilver/template/portal/modules/custom_center.html b/root/styles/prosilver/template/portal/modules/custom_center.html
new file mode 100644
index 00000000..86a4288e
--- /dev/null
+++ b/root/styles/prosilver/template/portal/modules/custom_center.html
@@ -0,0 +1,10 @@
+
+{$C_BLOCK_H_L}{$CUSTOM_TITLE}{$C_BLOCK_H_R}
+
+{$C_BLOCK_F_L}{$C_BLOCK_F_R}
\ No newline at end of file
diff --git a/root/styles/prosilver/template/portal/modules/custom_side.html b/root/styles/prosilver/template/portal/modules/custom_side.html
new file mode 100644
index 00000000..c29be614
--- /dev/null
+++ b/root/styles/prosilver/template/portal/modules/custom_side.html
@@ -0,0 +1,8 @@
+
+{$LR_BLOCK_H_L}
{$CUSTOM_TITLE}{$LR_BLOCK_H_R}
+
+{$LR_BLOCK_F_L}{$LR_BLOCK_F_R}
\ No newline at end of file
diff --git a/root/styles/prosilver/template/portal/portal_body.html b/root/styles/prosilver/template/portal/portal_body.html
index 2ad336f5..5149f919 100644
--- a/root/styles/prosilver/template/portal/portal_body.html
+++ b/root/styles/prosilver/template/portal/portal_body.html
@@ -17,6 +17,8 @@
+
+
@@ -28,6 +30,8 @@
+
+
@@ -38,6 +42,8 @@
+
+
@@ -52,6 +58,8 @@
+
+
@@ -63,6 +71,8 @@
+
+
diff --git a/root/styles/prosilver/theme/images/portal/portal_custom.png b/root/styles/prosilver/theme/images/portal/portal_custom.png
new file mode 100644
index 00000000..f9c503e8
Binary files /dev/null and b/root/styles/prosilver/theme/images/portal/portal_custom.png differ