diff --git a/web/app/Helpers/GridHelper.php b/web/app/Helpers/GridHelper.php
index ca88131..ac6d2f1 100644
--- a/web/app/Helpers/GridHelper.php
+++ b/web/app/Helpers/GridHelper.php
@@ -38,6 +38,6 @@ class GridHelper
public static function createScript($scripts = [], $arguments = [])
{
-
+ // TODO: XlXi: this when we get the grid working with the site
}
}
diff --git a/web/app/Helpers/QAaMBHelper.php b/web/app/Helpers/QAaMBHelper.php
new file mode 100644
index 0000000..42eb6b6
--- /dev/null
+++ b/web/app/Helpers/QAaMBHelper.php
@@ -0,0 +1,141 @@
+ConnectServer( '127.0.0.1', 'root\CIMV2' );
+ $WbemServices->Security_->ImpersonationLevel = 3;
+ return $WbemServices->ExecQuery( $query );
+ } catch ( \com_exception $e ) {
+ echo $e->getMessage();
+ }
+ } elseif ( ! extension_loaded( 'com_dotnet' ) )
+ trigger_error( 'It seems that the COM is not enabled in your php.ini', E_USER_WARNING );
+ else {
+ $err = error_get_last();
+ trigger_error( $err['message'], E_USER_WARNING );
+ }
+
+ return false;
+ }
+
+ public static function getSystemMemoryInfo($output_key = '')
+ {
+ return cache()->remember('QAaMB-Memory-Info', 5, function(){
+ $keys = array('MemTotal', 'MemFree', 'MemAvailable', 'SwapTotal', 'SwapFree');
+ $result = array();
+
+ try {
+ if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') {
+ // LINUX
+
+ $proc_dir = '/proc/';
+ $data = _dir_in_allowed_path( $proc_dir ) ? @file( $proc_dir . 'meminfo' ) : false;
+ if ( is_array( $data ) )
+ foreach ( $data as $d ) {
+ if ( 0 == strlen( trim( $d ) ) )
+ continue;
+ $d = preg_split( '/:/', $d );
+ $key = trim( $d[0] );
+ if ( ! in_array( $key, $keys ) )
+ continue;
+ $value = 1000 * floatval( trim( str_replace( ' kB', '', $d[1] ) ) );
+ $result[$key] = $value;
+ }
+ } else {
+ // WINDOWS
+
+ $wmi_found = false;
+ if ( $wmi_query = self::wmiWBemLocatorQuery(
+ "SELECT FreePhysicalMemory,FreeVirtualMemory,TotalSwapSpaceSize,TotalVirtualMemorySize,TotalVisibleMemorySize FROM Win32_OperatingSystem" ) ) {
+ foreach($wmi_query as $r) {
+ $result['MemFree'] = $r->FreePhysicalMemory * 1024;
+ $result['MemAvailable'] = $r->FreeVirtualMemory * 1024;
+ $result['SwapFree'] = $r->TotalSwapSpaceSize * 1024;
+ $result['SwapTotal'] = $r->TotalVirtualMemorySize * 1024;
+ $result['MemTotal'] = $r->TotalVisibleMemorySize * 1024;
+ $wmi_found = true;
+ }
+ }
+ }
+ } catch(Exception $e) {
+ echo $e->getMessage();
+ }
+ return empty($output_key) || !isset($result[$output_key]) ? $result : $result[$output_key];
+ });
+ }
+
+ public static function getSystemCpuInfo($output_key = '')
+ {
+ return cache()->remember('QAaMB-Cpu-Info', 5, function(){
+ $result = 0;
+
+ try {
+ if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') {
+ // LINUX
+
+ return sys_getloadavg();
+ } else {
+ // WINDOWS
+
+ $wmi_found = false;
+ if ( $wmi_query = self::wmiWBemLocatorQuery(
+ "SELECT LoadPercentage FROM Win32_Processor" ) ) {
+ foreach($wmi_query as $r) {
+ $result = $r->LoadPercentage / 100;
+ $wmi_found = true;
+ }
+ }
+ }
+ } catch(Exception $e) {
+ echo $e->getMessage();
+ }
+ return empty($output_key) || !isset($result[$output_key]) ? $result : $result[$output_key];
+ });
+ }
+
+ public static function memoryString($memory)
+ {
+ $unit = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
+ return @round($memory/pow(1024,($i=floor(log($memory,1024)))),2).' '.$unit[$i];
+ }
+
+ public static function getMemoryUsage()
+ {
+ $memoryInfo = self::getSystemMemoryInfo();
+
+ return sprintf(
+ '%s of %s (%s%%)
%s Free',
+ self::memoryString($memoryInfo['MemTotal'] - $memoryInfo['MemFree']),
+ self::memoryString($memoryInfo['MemTotal']),
+ round(self::getMemoryPercentage() * 100),
+ self::memoryString($memoryInfo['MemFree'])
+ );
+ }
+
+ public static function getMemoryPercentage()
+ {
+ $memoryInfo = self::getSystemMemoryInfo();
+
+ return ($memoryInfo['MemTotal'] - $memoryInfo['MemFree']) / $memoryInfo['MemTotal'];
+ }
+
+ public static function getCpuUsage()
+ {
+ return sprintf(
+ '%s%% CPU Usage',
+ round(self::getSystemCpuInfo() * 100)
+ );
+ }
+}
diff --git a/web/app/Http/Controllers/Api/CommentsController.php b/web/app/Http/Controllers/Api/CommentsController.php
index a5f5c80..4de98f2 100644
--- a/web/app/Http/Controllers/Api/CommentsController.php
+++ b/web/app/Http/Controllers/Api/CommentsController.php
@@ -47,11 +47,10 @@ class CommentsController extends Controller
foreach($comments as $comment) {
// TODO: XlXi: user profile link
- // TODO: XlXi: user thumbnail
$poster = [
'name' => $comment->user->username,
'thumbnail' => 'https://www.gtoria.local/images/testing/headshot.png',
- 'url' => 'https://gtoria.local/todo123'
+ 'url' => $comment->user->getProfileUrl()
];
$postDate = $comment['updated_at'];
diff --git a/web/app/Http/Controllers/Api/FeedController.php b/web/app/Http/Controllers/Api/FeedController.php
index 47f0ea1..77179e4 100644
--- a/web/app/Http/Controllers/Api/FeedController.php
+++ b/web/app/Http/Controllers/Api/FeedController.php
@@ -38,12 +38,11 @@ class FeedController extends Controller
if($post['poster_type'] == 'user') {
$user = User::where('id', $post['poster_id'])->first();
- // TODO: XlXi: user profile link
$poster = [
'type' => 'User',
'name' => $user->username,
'thumbnail' => 'https://www.gtoria.local/images/testing/headshot.png',
- 'url' => 'https://gtoria.local/todo123'
+ 'url' => $user->getProfileUrl()
];
}
diff --git a/web/app/Http/Controllers/Api/ShopController.php b/web/app/Http/Controllers/Api/ShopController.php
index f9a9ede..1d7f313 100644
--- a/web/app/Http/Controllers/Api/ShopController.php
+++ b/web/app/Http/Controllers/Api/ShopController.php
@@ -72,12 +72,11 @@ class ShopController extends Controller
foreach($assets as $asset) {
$creator = $asset->user;
- // TODO: XlXi: creator profile url
array_push($data, [
'Name' => $asset->name,
'Creator' => [
'Name' => $creator->username,
- 'Url' => 'todo123'
+ 'Url' => $creator->getProfileUrl()
],
'Thumbnail' => $asset->getThumbnail(),
'Url' => route('shop.asset', ['asset' => $asset->id, 'assetName' => Str::slug($asset->name, '-')])
diff --git a/web/app/Http/Controllers/Web/ProfileController.php b/web/app/Http/Controllers/Web/ProfileController.php
new file mode 100644
index 0000000..f33b60a
--- /dev/null
+++ b/web/app/Http/Controllers/Web/ProfileController.php
@@ -0,0 +1,19 @@
+with([
+ 'title' => sprintf('Profile of %s', $user->username),
+ 'user' => $user
+ ]);
+ }
+}
diff --git a/web/app/Http/Controllers/Web/TestController.php b/web/app/Http/Controllers/Web/TestController.php
new file mode 100644
index 0000000..3181e6b
--- /dev/null
+++ b/web/app/Http/Controllers/Web/TestController.php
@@ -0,0 +1,35 @@
+OpenJob(SoapService::MakeJobJSON('test', 10, 0, 0, 'test render', $testScript));
+
+ return response(base64_decode($result->OpenJobExResult->LuaValue[0]->value))
+ ->header('Content-Type', 'image/png');
+ }
+}
\ No newline at end of file
diff --git a/web/app/Http/Middleware/Administrator.php b/web/app/Http/Middleware/Administrator.php
new file mode 100644
index 0000000..7d8c80e
--- /dev/null
+++ b/web/app/Http/Middleware/Administrator.php
@@ -0,0 +1,24 @@
+isAdmin())
+ return $next($request);
+
+ return abort(403);
+ }
+}
diff --git a/web/app/Models/Roleset.php b/web/app/Models/Roleset.php
new file mode 100644
index 0000000..8d0dc85
--- /dev/null
+++ b/web/app/Models/Roleset.php
@@ -0,0 +1,11 @@
+id)
->where('accepted', false);
}
+
+ public function getProfileUrl()
+ {
+ return route('user.profile', ['user' => $this->id]);
+ }
+
+ public function _hasRolesetInternal($roleName)
+ {
+ $roleset = Roleset::where('Name', $roleName)->first();
+ if(
+ UserRoleset::where('Roleset_id', $roleset->id)
+ ->where('User_id', Auth::user()->id)
+ ->exists()
+ )
+ return true;
+
+ return false;
+ }
+
+ public function hasRoleset($roleName)
+ {
+ if(!Auth::check())
+ return false;
+
+ $roleName = strtolower($roleName);
+
+ // Special cases for Owner and Administrator rolesets
+ if($roleName == 'moderator') {
+ return (
+ $this->_hasRolesetInternal('Owner') ||
+ $this->_hasRolesetInternal('Administrator') ||
+ $this->_hasRolesetInternal('Moderator')
+ );
+ } elseif($roleName == 'administrator') {
+ return (
+ $this->_hasRolesetInternal('Owner') ||
+ $this->_hasRolesetInternal('Administrator')
+ );
+ }
+
+ return $this->_hasRolesetInternal($roleName);
+ }
}
diff --git a/web/app/Models/UserRoleset.php b/web/app/Models/UserRoleset.php
new file mode 100644
index 0000000..282af08
--- /dev/null
+++ b/web/app/Models/UserRoleset.php
@@ -0,0 +1,21 @@
+belongsTo(Roleset::class, 'Roleset_id');
+ }
+
+ public function user()
+ {
+ return $this->belongsTo(User::class, 'User_id');
+ }
+}
diff --git a/web/app/Providers/AppServiceProvider.php b/web/app/Providers/AppServiceProvider.php
index 5990509..34fc9ce 100644
--- a/web/app/Providers/AppServiceProvider.php
+++ b/web/app/Providers/AppServiceProvider.php
@@ -2,7 +2,7 @@
namespace App\Providers;
-use Illuminate\Support\Facades\Request;
+use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
@@ -24,6 +24,28 @@ class AppServiceProvider extends ServiceProvider
*/
public function boot()
{
- //
+ Blade::directive('owner', function() {
+ return 'hasRoleset(\'Owner\')): ?>';
+ });
+
+ Blade::directive('endowner', function() {
+ return '';
+ });
+
+ Blade::directive('admin', function() {
+ return 'hasRoleset(\'Administrator\')): ?>';
+ });
+
+ Blade::directive('endadmin', function() {
+ return '';
+ });
+
+ Blade::directive('moderator', function() {
+ return 'hasRoleset(\'Moderator\')): ?>';
+ });
+
+ Blade::directive('endmoderator', function() {
+ return '';
+ });
}
}
diff --git a/web/database/migrations/2022_08_04_193626_create_rolesets_table.php b/web/database/migrations/2022_08_04_193626_create_rolesets_table.php
new file mode 100644
index 0000000..b637c43
--- /dev/null
+++ b/web/database/migrations/2022_08_04_193626_create_rolesets_table.php
@@ -0,0 +1,32 @@
+id();
+ $table->string('Name');
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::dropIfExists('rolesets');
+ }
+};
diff --git a/web/database/migrations/2022_08_04_211729_create_user_rolesets_table.php b/web/database/migrations/2022_08_04_211729_create_user_rolesets_table.php
new file mode 100644
index 0000000..99c4853
--- /dev/null
+++ b/web/database/migrations/2022_08_04_211729_create_user_rolesets_table.php
@@ -0,0 +1,33 @@
+id();
+ $table->unsignedBigInteger('Roleset_id');
+ $table->unsignedBigInteger('User_id');
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::dropIfExists('user_rolesets');
+ }
+};
diff --git a/web/database/seeders/DatabaseSeeder.php b/web/database/seeders/DatabaseSeeder.php
index 6639aea..6a1c73a 100644
--- a/web/database/seeders/DatabaseSeeder.php
+++ b/web/database/seeders/DatabaseSeeder.php
@@ -16,7 +16,8 @@ class DatabaseSeeder extends Seeder
{
$this->call([
//FFlagSeeder::class,
- WebConfigurationSeeder::class
+ WebConfigurationSeeder::class,
+ RolesetSeeder::class
]);
}
}
diff --git a/web/database/seeders/RolesetSeeder.php b/web/database/seeders/RolesetSeeder.php
new file mode 100644
index 0000000..c3c3e41
--- /dev/null
+++ b/web/database/seeders/RolesetSeeder.php
@@ -0,0 +1,26 @@
+ 'Owner']);
+ Roleset::create(['name' => 'Administrator']);
+ Roleset::create(['name' => 'Moderator']);
+ Roleset::create(['name' => 'ProtectedUser']);
+ Roleset::create(['name' => 'BetaTester']);
+ Roleset::create(['name' => 'QATester']);
+ Roleset::create(['name' => 'Soothsayer']);
+ }
+}
diff --git a/web/resources/js/components/ThumbnailToolbar.js b/web/resources/js/components/ThumbnailToolbar.js
new file mode 100644
index 0000000..e69de29
diff --git a/web/resources/views/layouts/nav.blade.php b/web/resources/views/layouts/nav.blade.php
index a504409..8e326e9 100644
--- a/web/resources/views/layouts/nav.blade.php
+++ b/web/resources/views/layouts/nav.blade.php
@@ -17,108 +17,217 @@
];
@endphp
-