diff --git a/root/language/en/mods/portal/portal_birthday_list_module.php b/root/language/en/mods/portal/portal_birthday_list_module.php
new file mode 100644
index 00000000..ffe79a07
--- /dev/null
+++ b/root/language/en/mods/portal/portal_birthday_list_module.php
@@ -0,0 +1,46 @@
+ 'In the next %s days',
+ 'NO_BIRTHDAYS_AHEAD' => 'No members have a birthday within this period of time.',
+
+ // ACP
+ 'ACP_PORTAL_BIRTHDAYS_SETTINGS' => 'Birthdays Settings',
+ 'ACP_PORTAL_BIRTHDAYS_SETTINGS_EXP' => 'This is where you customize the birthday block.',
+ 'PORTAL_BIRTHDAYS' => 'Birthday block',
+ 'PORTAL_BIRTHDAYS_EXP' => 'Display this block on the portal.',
+ 'PORTAL_BIRTHDAYS_AHEAD' => 'Birthdays ahead days',
+ 'PORTAL_BIRTHDAYS_AHEAD_EXP' => 'How many days to look ahead for future birthdays.
"0" will disable the ahead birthdays list.',
+));
+
+?>
\ No newline at end of file
diff --git a/root/language/en/mods/portal/portal_stylechanger_module.php b/root/language/en/mods/portal/portal_stylechanger_module.php
new file mode 100644
index 00000000..5dd544be
--- /dev/null
+++ b/root/language/en/mods/portal/portal_stylechanger_module.php
@@ -0,0 +1,38 @@
+ 'Board style',
+ 'STYLE_CHOOSE' => 'Select a style',
+));
+
+?>
\ No newline at end of file
diff --git a/root/portal/modules/portal_birthday_list.php b/root/portal/modules/portal_birthday_list.php
new file mode 100644
index 00000000..8640a4f8
--- /dev/null
+++ b/root/portal/modules/portal_birthday_list.php
@@ -0,0 +1,159 @@
+lang}/mods/portal/"
+ */
+ var $language = 'portal_birthday_list_module';
+
+ function get_template_side($module_id)
+ {
+ global $config, $template, $db, $user;
+
+ // Generate birthday list if required ... / borrowed from index.php 3.0.6
+ $birthday_list = $birthday_ahead_list = '';
+ if ($config['load_birthdays'] && $config['allow_birthdays'])
+ {
+ $now = getdate(time() + $user->timezone + $user->dst - date('Z'));
+ $cache_days = $config['board3_birthdays_ahead'];
+ $sql_days = '';
+ while ($cache_days > 0)
+ {
+ $day = getdate(time() + 86400 * $cache_days + $user->timezone + $user->dst - date('Z'));
+ $sql_days .= " OR u.user_birthday LIKE '" . $db->sql_escape(sprintf('%2d-%2d-', $day['mday'], $day['mon'])) . "%'";
+ $cache_days--;
+ }
+
+ switch ($db->sql_layer)
+ {
+ case 'mssql':
+ case 'mssql_odbc':
+ $order_by = 'u.user_birthday ASC';
+ break;
+
+ default:
+ $order_by = 'SUBSTRING(u.user_birthday FROM 4 FOR 2) ASC, SUBSTRING(u.user_birthday FROM 1 FOR 2) ASC, u.username_clean ASC';
+ break;
+ }
+ $now = getdate(time() + $user->timezone + $user->dst - date('Z'));
+ $sql = 'SELECT u.user_id, u.username, u.user_colour, u.user_birthday
+ FROM ' . USERS_TABLE . ' u
+ LEFT JOIN ' . BANLIST_TABLE . " b ON (u.user_id = b.ban_userid)
+ WHERE (b.ban_id IS NULL
+ OR b.ban_exclude = 1)
+ AND (u.user_birthday LIKE '" . $db->sql_escape(sprintf('%2d-%2d-', $now['mday'], $now['mon'])) . "%' {$sql_days})
+ AND u.user_type IN (" . USER_NORMAL . ', ' . USER_FOUNDER . ')
+ ORDER BY ' . $order_by;
+ $result = $db->sql_query($sql);
+ $today = sprintf('%2d-%2d-', $now['mday'], $now['mon']);
+
+ while ($row = $db->sql_fetchrow($result))
+ {
+ if (substr($row['user_birthday'], 0, 6) == $today)
+ {
+ $birthday_list .= '
' . get_username_string('full', $row['user_id'], $row['username'], $row['user_colour']) . '';
+ if ($age = (int) substr($row['user_birthday'], -4))
+ {
+ $birthday_list .= ' (' . ($now['year'] - $age) . ')';
+ }
+ $birthday_list .= '
';
+ }
+ elseif ($config['board3_birthdays_ahead'] > 0)
+ {
+ $birthday_ahead_list .= '
' . get_username_string('full', $row['user_id'], $row['username'], $row['user_colour']) . '';
+ if ($age = (int) substr($row['user_birthday'], -4))
+ {
+ $birthday_ahead_list .= ' (' . ($now['year'] - $age) . ')';
+ }
+ $birthday_ahead_list .= '
';
+ }
+ }
+ $db->sql_freeresult($result);
+ }
+
+ // Assign index specific vars
+ $template->assign_vars(array(
+ 'BIRTHDAY_LIST' => $birthday_list,
+ 'BIRTHDAYS_AHEAD_LIST' => ($config['board3_birthdays_ahead']) ? $birthday_ahead_list : '',
+ 'L_BIRTHDAYS_AHEAD' => sprintf($user->lang['BIRTHDAYS_AHEAD'], $config['board3_birthdays_ahead']),
+ 'S_DISPLAY_BIRTHDAY_LIST' => ($config['load_birthdays']) ? true : false,
+ 'S_DISPLAY_BIRTHDAY_AHEAD_LIST' => ($config['board3_birthdays_ahead'] > 0) ? true : false,
+ ));
+
+ return 'birthdays_side.html';
+ }
+
+ function get_template_acp($module_id)
+ {
+ return array(
+ 'title' => 'ACP_PORTAL_BIRTHDAYS_SETTINGS',
+ 'vars' => array(
+ 'legend1' => 'ACP_PORTAL_BIRTHDAYS_SETTINGS',
+ 'board3_birthdays_ahead' => array('lang' => 'PORTAL_BIRTHDAYS_AHEAD', 'validate' => 'int', 'type' => 'text:3:3', 'explain' => true),
+ ),
+ );
+ }
+
+ /**
+ * API functions
+ */
+ function install($module_id)
+ {
+ set_config('board3_birthdays_ahead', 30);
+ return true;
+ }
+
+ function uninstall($module_id)
+ {
+ global $db;
+
+ $del_config = array(
+ 'board3_birthdays_ahead',
+ );
+ $sql = 'DELETE FROM ' . CONFIG_TABLE . '
+ WHERE ' . $db->sql_in_set('config_name', $del_config);
+ return $db->sql_query($sql);
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/root/portal/modules/portal_stylechanger.php b/root/portal/modules/portal_stylechanger.php
new file mode 100644
index 00000000..5be216fe
--- /dev/null
+++ b/root/portal/modules/portal_stylechanger.php
@@ -0,0 +1,119 @@
+lang}/mods/portal/"
+ */
+ var $language = 'portal_stylechanger_module';
+
+ function get_template_side($module_id)
+ {
+ global $config, $template, $db, $phpEx;
+
+ $style_count = 0;
+ $style_select = '';
+ $sql = 'SELECT style_id, style_name
+ FROM ' . STYLES_TABLE . '
+ WHERE style_active = 1
+ ORDER BY LOWER(style_name) ASC';
+ $result = $db->sql_query($sql);
+ while ($row = $db->sql_fetchrow($result))
+ {
+ $style = request_var('style', 0);
+ if($style)
+ {
+ $url = str_replace('style=' . $style, 'style=' . $row['style_id'], append_sid("{$phpbb_root_path}portal.$phpEx"));
+ }
+ else
+ {
+ $url = append_sid("{$phpbb_root_path}portal.$phpEx", 'style=' . $row['style_id']);
+ }
+ ++$style_count;
+ $style_select .= '';
+ }
+ $db->sql_freeresult($result);
+ if(strlen($style_select))
+ {
+ $template->assign_var('STYLE_SELECT', $style_select);
+ }
+
+
+ // Assign specific vars
+ $template->assign_vars(array(
+ 'S_STYLE_OPTIONS' => ($config['override_user_style'] || $style_count < 2) ? '' : style_select($user->data['user_style']),
+ 'S_DISPLAY_CHANGE_STYLE' => true,
+ ));
+
+ return 'stylechanger_side.html';
+ }
+
+ function get_template_acp($module_id)
+ {
+ return array();
+ }
+
+ /**
+ * API functions
+ */
+ function install($module_id)
+ {
+ set_config('portal_' . $module_id . '_configname', 'Hello World!');
+ set_config('portal_' . $module_id . '_configname2', 1337);
+ return true;
+ }
+
+ function uninstall($module_id)
+ {
+ global $db;
+
+ $del_config = array(
+ 'portal_' . $module_id . '_configname',
+ 'portal_' . $module_id . '_configname2',
+ );
+ $sql = 'DELETE FROM ' . CONFIG_TABLE . '
+ WHERE ' . $db->sql_in_set('config_name', $del_config);
+ return $db->sql_query($sql);
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/root/styles/prosilver/template/portal/modules/birthdays_side.html b/root/styles/prosilver/template/portal/modules/birthdays_side.html
index c1673c22..5b3cfa77 100644
--- a/root/styles/prosilver/template/portal/modules/birthdays_side.html
+++ b/root/styles/prosilver/template/portal/modules/birthdays_side.html
@@ -1,15 +1,18 @@
{$LR_BLOCK_H_L}
{L_BIRTHDAYS}{$LR_BLOCK_H_R}
-
- {L_CONGRATULATIONS}:
{BIRTHDAY_LIST}
-
- {L_NO_BIRTHDAYS}
-
-{$LR_BLOCK_F_L}{$LR_BLOCK_F_R}
-{$LR_BLOCK_H_L}{L_BIRTHDAYS_AHEAD}{$LR_BLOCK_H_R}
-
- {BIRTHDAYS_AHEAD_LIST}
-
- {L_NO_BIRTHDAYS_AHEAD}
-
+
+ {L_CONGRATULATIONS}:
{BIRTHDAY_LIST}
+
+ {L_NO_BIRTHDAYS}
+
+
+