diff --git a/_developer_data/structure.sql b/_developer_data/structure.sql index 4c70568..46d77f5 100644 --- a/_developer_data/structure.sql +++ b/_developer_data/structure.sql @@ -187,6 +187,19 @@ INSERT INTO `sakura_emoticons` (`emote_string`, `emote_path`) VALUES (':what:', '/content/images/emoticons/what.png'), (':smug:', '/content/images/emoticons/smug.png'); + +DROP TABLE IF EXISTS `sakura_error_log`; +CREATE TABLE `sakura_error_log` ( + `id` varchar(32) COLLATE utf8_bin NOT NULL, + `timestamp` varchar(128) COLLATE utf8_bin NOT NULL, + `error_type` int(16) unsigned NOT NULL, + `error_line` int(32) unsigned NOT NULL, + `error_string` varchar(512) COLLATE utf8_bin NOT NULL, + `error_file` varchar(512) COLLATE utf8_bin NOT NULL, + `backtrace` text COLLATE utf8_bin NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; + + DROP TABLE IF EXISTS `sakura_faq`; CREATE TABLE `sakura_faq` ( `id` bigint(128) unsigned NOT NULL AUTO_INCREMENT COMMENT 'MySQL Generated ID used for sorting.', diff --git a/_sakura/changelog.json b/_sakura/changelog.json index 83eb030..6648efb 100644 --- a/_sakura/changelog.json +++ b/_sakura/changelog.json @@ -58,7 +58,8 @@ "20150902", "20150903", "20150904", - "20150905" + "20150905", + "20150906" ] @@ -2512,6 +2513,41 @@ "user": "Flashwave" } + ], + + "20150906": [ + + { + "type": "REM", + "change": "Removed unused URLs.", + "user": "Flashwave" + }, + { + "type": "ADD", + "change": "Add ability to hide certain settings modes from the menu.", + "user": "Flashwave" + }, + { + "type": "UPD", + "change": "Gave the error handler a massive update.", + "user": "Flashwave" + }, + { + "type": "FIX", + "change": "Made friendlist mobile friendly.", + "user": "Flashwave" + }, + { + "type": "FIX", + "change": "Fixed restricted.tpl not being referenced properly.", + "user": "Flashwave" + }, + { + "type": "ADD", + "change": "Added cookie notification.", + "user": "Flashwave" + } + ] } diff --git a/_sakura/components/Configuration.php b/_sakura/components/Configuration.php index 534edca..9b2b5fd 100644 --- a/_sakura/components/Configuration.php +++ b/_sakura/components/Configuration.php @@ -8,8 +8,8 @@ namespace Sakura; class Configuration { // Configuration data - private static $_LCNF; - private static $_DCNF; + private static $_LCNF = []; + private static $_DCNF = []; // Initialise configuration, does not contain database initialisation because explained below public static function init($local) { @@ -115,7 +115,7 @@ class Configuration { } // Get values from the configuration in the database - public static function getConfig($key) { + public static function getConfig($key, $returnNull = false) { // Check if the key that we're looking for exists if(array_key_exists($key, self::$_DCNF)) { @@ -123,6 +123,11 @@ class Configuration { // Then return the value return self::$_DCNF[$key]; + } elseif($returnNull) { + + // Avoid the error trigger if requested + return null; + } else { // Then return the value diff --git a/_sakura/components/Database.php b/_sakura/components/Database.php index 74c8ef2..82fe5a0 100644 --- a/_sakura/components/Database.php +++ b/_sakura/components/Database.php @@ -8,7 +8,7 @@ namespace Sakura; class Database { // Database container - private static $_DATABASE; + public static $_DATABASE; // Initialisation function public static function init($wrapper) { @@ -17,9 +17,12 @@ class Database { $wrapper = __NAMESPACE__ .'\DBWrapper\\'. strtolower($wrapper); // Check if the class exists - if(!class_exists($wrapper)) + if(!class_exists($wrapper)) { + trigger_error('Failed to load database wrapper', E_USER_ERROR); + } + // Initialise SQL wrapper self::$_DATABASE = new $wrapper; diff --git a/_sakura/components/Main.php b/_sakura/components/Main.php index 924967e..71e164e 100644 --- a/_sakura/components/Main.php +++ b/_sakura/components/Main.php @@ -114,10 +114,43 @@ class Main { // Error Handler public static function errorHandler($errno, $errstr, $errfile, $errline) { - // Set some variables to work with including A HUGE fallback hackjob for the templates folder + // Remove ROOT path from the error string and file location $errstr = str_replace(ROOT, '', $errstr); $errfile = str_replace(ROOT, '', $errfile); - $templates = ROOT .'_sakura/templates/'; + + // Attempt to log the error to the database + if(Database::$_DATABASE !== null) { + + // Encode backtrace data + $backtrace = base64_encode(json_encode(debug_backtrace())); + + // Check if this error has already been logged in the past + if($past = Database::fetch('error_log', false, ['backtrace' => [$backtrace, '=', true], 'error_string' => [$errstr, '=']])) { + + // If so assign the errid + $errid = $past['id']; + + } else { + + // Create an error ID + $errid = substr(md5(microtime()), rand(0, 22), 10); + + // Log the error + Database::insert('error_log', [ + + 'id' => $errid, + 'timestamp' => date("r"), + 'error_type' => $errno, + 'error_line' => $errline, + 'error_string' => $errstr, + 'error_file' => $errfile, + 'backtrace' => $backtrace + + ]); + + } + + } switch ($errno) { @@ -141,18 +174,78 @@ class Main { } - // Use file_get_contents instead of Twig in case the problem is related to twig - $errorPage = file_get_contents($templates. 'errorPage.tpl'); - - // str_replace {{ error }} on the error page with the error data - $error = str_replace('{{ error }}', $error, $errorPage); - // Truncate all previous outputs ob_clean(); ob_end_clean(); + // Build page + $errorPage = ' + + + + Sakura Internal Error + + + +
+

An error occurred while executing the script.

+
+

To prevent potential security risks or data loss Sakura has stopped execution of the script.

'; + +if(isset($errid)) { + + $errorPage .= '

The error and surrounding data has been logged.

+

'. (SAKURA_STABLE ? 'Report the following text to a staff member' : 'Logged as') .'

'. $errid .'
'; + +} else { + + $errorPage .= '

Sakura was not able to log this error which could mean that there was an error with the database connection. If you\'re the system administrator check the database credentials and make sure the server is running and if you\'re not please let the system administrator know about this error if it occurs again.

'; + +} + +if(!SAKURA_STABLE) { + $errorPage .= '

Summary

+
'. $error .'
+

Backtraces

'; + + foreach(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS) as $num => $trace) { + + $errorPage .= '

#'. $num .'

';
+
+        foreach($trace as $key => $val) {
+
+            $errorPage .= str_pad('['. $key .']', 12) .'=> '. (is_array($val) || is_object($val) ? json_encode($val) : $val) ."\r\n";
+
+        }
+
+        $errorPage .= '
'; + + } + +} + +$errorPage .= '
+ +
+ +'; + // Die and display error message - die($error); + die($errorPage); } diff --git a/_sakura/components/Urls.php b/_sakura/components/Urls.php index 5a2f0de..3e3aaad 100644 --- a/_sakura/components/Urls.php +++ b/_sakura/components/Urls.php @@ -66,8 +66,6 @@ class Urls { 'SETTINGS_INDEX' => ['/settings.php', '/settings'], 'SETTING_CAT' => ['/settings.php?cat=%s', '/settings/%s'], 'SETTING_MODE' => ['/settings.php?cat=%s&mode=%s', '/settings/%s/%s'], - 'MESSAGES_INDEX' => ['/settings.php?cat=messages', '/messages'], - 'MESSAGES_MODE' => ['/settings.php?cat=messages&mode=%s', '/messages/%s'], // Friend Actions 'FRIEND_ACTION' => ['/settings.php?friend-action=true', '/friends'], diff --git a/_sakura/config/config.example.ini b/_sakura/config/config.example.ini index c4faf36..b82df57 100644 --- a/_sakura/config/config.example.ini +++ b/_sakura/config/config.example.ini @@ -44,13 +44,3 @@ whoisservers = config/whois.json ; JSON file containing ISO 3166 country codes iso3166 = config/iso3166.json - - -; Sock Chat extensions configuration -; These only work properly if Sock Chat uses the same database as the rest of Sakura -[sockchat] -; Set whether the Sock Chat extensions should be used or not -enabled = true - -; The table prefix used for Sock Chat -prefix = sock_ diff --git a/_sakura/sakura.php b/_sakura/sakura.php index 72310b5..ae8ffa3 100644 --- a/_sakura/sakura.php +++ b/_sakura/sakura.php @@ -8,7 +8,7 @@ namespace Sakura; // Define Sakura version -define('SAKURA_VERSION', '20150905'); +define('SAKURA_VERSION', '20150906'); define('SAKURA_VLABEL', 'Eminence'); define('SAKURA_COLOUR', '#6C3082'); define('SAKURA_STABLE', false); diff --git a/_sakura/templates/errorPage.tpl b/_sakura/templates/errorPage.tpl deleted file mode 100644 index bf41c07..0000000 --- a/_sakura/templates/errorPage.tpl +++ /dev/null @@ -1,78 +0,0 @@ - - - - - Sakura Internal Error - - - -
-

An Error occurred while executing the script.

-
-

To prevent potential security risks PHP has stopped execution of the script.

-

PHP Reported the following error log:

-
- {{ error }} -
-

If you have an account on BitBucket please go to the issues section and report the error listed above (do a check to see if it hasn't been reported yet as well).

-
-
- Contact the System Operator at me@flash.moe or check our Status Page and Twitter Account to see if anything is going on. -
-
- - diff --git a/_sakura/templates/yuuno/elements/restricted.tpl b/_sakura/templates/yuuno/elements/restricted.tpl index 508e43c..e69de29 100644 --- a/_sakura/templates/yuuno/elements/restricted.tpl +++ b/_sakura/templates/yuuno/elements/restricted.tpl @@ -1,4 +0,0 @@ -
-

You aren't allowed to view this page!

- Please make sure that you're logged in and are supposed to be able to access this page. If you think this was a mistake please contact a staff member. -
diff --git a/_sakura/templates/yuuno/elements/settingsNav.tpl b/_sakura/templates/yuuno/elements/settingsNav.tpl index b1c6fb4..46f084f 100644 --- a/_sakura/templates/yuuno/elements/settingsNav.tpl +++ b/_sakura/templates/yuuno/elements/settingsNav.tpl @@ -5,7 +5,7 @@ {% for catname,category in pages %}
{{ category.title }}
{% for mname,mode in category.modes %} - {% if mode.access %} + {% if mode.access and mode.menu %} {{ mode.title }} {% endif %} {% endfor %} diff --git a/_sakura/templates/yuuno/global/master.tpl b/_sakura/templates/yuuno/global/master.tpl index 5cbe872..52c356b 100644 --- a/_sakura/templates/yuuno/global/master.tpl +++ b/_sakura/templates/yuuno/global/master.tpl @@ -46,6 +46,7 @@ }, + "siteName": "{{ sakura.siteName }}", "urlMain": "{{ sakura.urlMain }}", "content": "{{ sakura.contentPath }}", "resources": "{{ sakura.resources }}", @@ -150,6 +151,17 @@ {% endif %} + if(!cookieData('get', sakuraVars.cookie.prefix +'accept_cookies')) { + + notifyUI({ + "title": sakuraVars.siteName + " uses cookies!", + "text": "Click this if you're OK with that and want to hide this message.", + "img": "FONT:fa-asterisk", + "link": "javascript:cookieData('set', '"+ sakuraVars.cookie.prefix +"accept_cookies', 'true');notifyClose(this.parentNode.id);" + }); + + } + }); diff --git a/_sakura/templates/yuuno/global/restricted.tpl b/_sakura/templates/yuuno/global/restricted.tpl new file mode 100644 index 0000000..1724a26 --- /dev/null +++ b/_sakura/templates/yuuno/global/restricted.tpl @@ -0,0 +1,10 @@ +{% extends 'global/master.tpl' %} + +{% block content %} +
+
+

You aren't allowed to view this page!

+ Please make sure that you're logged in and are supposed to be able to access this page. If you think this was a mistake please contact a staff member. +
+
+{% endblock %} diff --git a/_sakura/templates/yuuno/settings/messages.read.tpl b/_sakura/templates/yuuno/settings/messages.read.tpl new file mode 100644 index 0000000..e69de29 diff --git a/main/content/data/yuuno/css/yuuno.css b/main/content/data/yuuno/css/yuuno.css index 9075603..74e10d6 100644 --- a/main/content/data/yuuno/css/yuuno.css +++ b/main/content/data/yuuno/css/yuuno.css @@ -1416,6 +1416,7 @@ a#gotop.exit { border-radius: 3px; box-shadow: inset 0 0 1px #9475B2; background: #E4CFFF; + transition: .2s; } .settings .friends-list > div:not(:last-child):hover { @@ -1436,7 +1437,7 @@ a#gotop.exit { .settings .friends-list > div > .friends-list-actions { display: none; - background: linear-gradient(0deg, #9475B2, #C2AFFE) #9475B2; + background: linear-gradient(0deg, #9475B2, transparent) transparent; } .settings .friends-list > div > .friends-list-actions > a { @@ -1477,6 +1478,18 @@ a#gotop.exit { width: 100%; } +@media (max-width: 1024px) { + + .settings .friends-list > div:not(:last-child) { + margin-bottom: 6px; + } + + .settings .friends-list > div > .friends-list-actions { + display: block; + } + +} + /* * Support page Styling */ diff --git a/main/content/data/yuuno/js/yuuno.js b/main/content/data/yuuno/js/yuuno.js index 20259ac..b388fae 100644 --- a/main/content/data/yuuno/js/yuuno.js +++ b/main/content/data/yuuno/js/yuuno.js @@ -77,7 +77,7 @@ function notifyUI(content) { if(content.link) { notif .setAttribute('sakurahref', content.link); - notifContent.setAttribute('onclick', 'notifyOpen(this.parentNode.id);'); + notifContent.setAttribute('onclick', content.link.substring(0, 11) == 'javascript:' ? content.link.substring(11) : 'notifyOpen(this.parentNode.id);'); } notifContent .appendChild(notifTitle); diff --git a/main/settings.php b/main/settings.php index 61f986e..8683c08 100644 --- a/main/settings.php +++ b/main/settings.php @@ -672,7 +672,8 @@ if(Users::checkLogin()) { 'Welcome to the Settings Panel. From here you can monitor, view and update your profile and preferences.' ], - 'access' => !$currentUser->checkPermission('SITE', 'DEACTIVATED') + 'access' => !$currentUser->checkPermission('SITE', 'DEACTIVATED'), + 'menu' => true ], 'profile' => [ @@ -683,7 +684,8 @@ if(Users::checkLogin()) { 'These are the external account links etc. on your profile, shouldn\'t need any additional explanation for this one.' ], - 'access' => $currentUser->checkPermission('SITE', 'ALTER_PROFILE') + 'access' => $currentUser->checkPermission('SITE', 'ALTER_PROFILE'), + 'menu' => true ], 'options' => [ @@ -694,7 +696,8 @@ if(Users::checkLogin()) { 'These are a few personalisation options for the site while you\'re logged in.' ], - 'access' => !$currentUser->checkPermission('SITE', 'DEACTIVATED') + 'access' => !$currentUser->checkPermission('SITE', 'DEACTIVATED'), + 'menu' => true ], 'groups' => [ @@ -705,7 +708,8 @@ if(Users::checkLogin()) { '{{ user.colour }}' ], - 'access' => $currentUser->checkPermission('SITE', 'JOIN_GROUPS') + 'access' => $currentUser->checkPermission('SITE', 'JOIN_GROUPS'), + 'menu' => true ] @@ -726,7 +730,8 @@ if(Users::checkLogin()) { 'Manage your friends.' ], - 'access' => $currentUser->checkPermission('SITE', 'MANAGE_FRIENDS') + 'access' => $currentUser->checkPermission('SITE', 'MANAGE_FRIENDS'), + 'menu' => true ], 'requests' => [ @@ -737,7 +742,8 @@ if(Users::checkLogin()) { 'Handle friend requests.' ], - 'access' => $currentUser->checkPermission('SITE', 'MANAGE_FRIENDS') + 'access' => $currentUser->checkPermission('SITE', 'MANAGE_FRIENDS'), + 'menu' => true ] @@ -758,7 +764,8 @@ if(Users::checkLogin()) { 'The list of messages you\'ve received.' ], - 'access' => $currentUser->checkPermission('SITE', 'USE_MESSAGES') + 'access' => $currentUser->checkPermission('SITE', 'USE_MESSAGES'), + 'menu' => true ], 'sent' => [ @@ -769,7 +776,8 @@ if(Users::checkLogin()) { 'The list of messages you\'ve sent to other users.' ], - 'access' => $currentUser->checkPermission('SITE', 'USE_MESSAGES') + 'access' => $currentUser->checkPermission('SITE', 'USE_MESSAGES'), + 'menu' => true ], 'compose' => [ @@ -780,7 +788,20 @@ if(Users::checkLogin()) { 'Write a new message.' ], - 'access' => $currentUser->checkPermission('SITE', 'SEND_MESSAGES') + 'access' => $currentUser->checkPermission('SITE', 'SEND_MESSAGES'), + 'menu' => true + + ], + 'read' => [ + + 'title' => 'Read', + 'description' => [ + + 'Read a message.' + + ], + 'access' => $currentUser->checkPermission('SITE', 'USE_MESSAGES'), + 'menu' => false ] @@ -801,7 +822,8 @@ if(Users::checkLogin()) { 'The history of notifications that have been sent to you.' ], - 'access' => !$currentUser->checkPermission('SITE', 'DEACTIVATED') + 'access' => !$currentUser->checkPermission('SITE', 'DEACTIVATED'), + 'menu' => true ] @@ -824,7 +846,8 @@ if(Users::checkLogin()) { ], - 'access' => $currentUser->checkPermission('SITE', 'CHANGE_AVATAR') + 'access' => $currentUser->checkPermission('SITE', 'CHANGE_AVATAR'), + 'menu' => true ], 'background' => [ @@ -836,7 +859,8 @@ if(Users::checkLogin()) { 'Maximum image size is {{ background.max_width }}x{{ background.max_height }}, minimum image size is {{ background.min_width }}x{{ background.min_height }}, maximum file size is {{ background.max_size_view }}.' ], - 'access' => (isset($currentUser->data['userData']['profileBackground']) && $currentUser->checkPermission('SITE', 'CHANGE_BACKGROUND')) || $currentUser->checkPermission('SITE', 'CREATE_BACKGROUND') + 'access' => (isset($currentUser->data['userData']['profileBackground']) && $currentUser->checkPermission('SITE', 'CHANGE_BACKGROUND')) || $currentUser->checkPermission('SITE', 'CREATE_BACKGROUND'), + 'menu' => true ], 'userpage' => [ @@ -847,7 +871,8 @@ if(Users::checkLogin()) { 'The custom text that is displayed on your profile.' ], - 'access' => (isset($currentUser->data['userData']['userPage']) && $currentUser->checkPermission('SITE', 'CHANGE_USERPAGE')) || $currentUser->checkPermission('SITE', 'CREATE_USERPAGE') + 'access' => (isset($currentUser->data['userData']['userPage']) && $currentUser->checkPermission('SITE', 'CHANGE_USERPAGE')) || $currentUser->checkPermission('SITE', 'CREATE_USERPAGE'), + 'menu' => true ] @@ -868,7 +893,8 @@ if(Users::checkLogin()) { 'You e-mail address is used for password recovery and stuff like that, we won\'t spam you ;).' ], - 'access' => $currentUser->checkPermission('SITE', 'CHANGE_EMAIL') + 'access' => $currentUser->checkPermission('SITE', 'CHANGE_EMAIL'), + 'menu' => true ], 'username' => [ @@ -880,7 +906,8 @@ if(Users::checkLogin()) { 'You can only change this once every 30 days so choose wisely.' ], - 'access' => $currentUser->checkPermission('SITE', 'CHANGE_USERNAME') + 'access' => $currentUser->checkPermission('SITE', 'CHANGE_USERNAME'), + 'menu' => true ], 'usertitle' => [ @@ -891,7 +918,8 @@ if(Users::checkLogin()) { 'That little piece of text displayed under your username on your profile.' ], - 'access' => $currentUser->checkPermission('SITE', 'CHANGE_USERTITLE') + 'access' => $currentUser->checkPermission('SITE', 'CHANGE_USERTITLE'), + 'menu' => true ], 'password' => [ @@ -902,7 +930,8 @@ if(Users::checkLogin()) { 'Used to authenticate with the site and certain related services.' ], - 'access' => $currentUser->checkPermission('SITE', 'CHANGE_PASSWORD') + 'access' => $currentUser->checkPermission('SITE', 'CHANGE_PASSWORD'), + 'menu' => true ], 'ranks' => [ @@ -913,7 +942,8 @@ if(Users::checkLogin()) { 'Manage what ranks you\'re in and what is set as your main rank. Your main rank is highlighted. You get the permissions of all of the ranks you\'re in combined.' ], - 'access' => $currentUser->checkPermission('SITE', 'ALTER_RANKS') + 'access' => $currentUser->checkPermission('SITE', 'ALTER_RANKS'), + 'menu' => true ] @@ -936,7 +966,8 @@ if(Users::checkLogin()) { 'If you get logged out after clicking one you\'ve most likely killed your current session, to make it easier to avoid this from happening your current session is highlighted.' ], - 'access' => $currentUser->checkPermission('SITE', 'MANAGE_SESSIONS') + 'access' => $currentUser->checkPermission('SITE', 'MANAGE_SESSIONS'), + 'menu' => true ], 'registrationkeys' => [ @@ -948,7 +979,8 @@ if(Users::checkLogin()) { 'Each user can generate 5 of these keys, bans and deactivates render these keys useless.' ], - 'access' => $currentUser->checkPermission('SITE', 'CREATE_REGKEYS') + 'access' => $currentUser->checkPermission('SITE', 'CREATE_REGKEYS'), + 'menu' => true ], 'deactivate' => [ @@ -959,7 +991,8 @@ if(Users::checkLogin()) { 'You can deactivate your account here if you want to leave :(.' ], - 'access' => $currentUser->checkPermission('SITE', 'DEACTIVATE_ACCOUNT') + 'access' => $currentUser->checkPermission('SITE', 'DEACTIVATE_ACCOUNT'), + 'menu' => true ] @@ -1084,8 +1117,6 @@ if(Users::checkLogin()) { $renderData['page']['title'] = 'Restricted!'; - print Templates::render('global/header.tpl', $renderData); - print Templates::render('elements/restricted.tpl', $renderData); - print Templates::render('global/footer.tpl', $renderData); + print Templates::render('global/restricted.tpl', $renderData); }