Skip to content

Commit c589a3a

Browse files
committed
Implemented Theme Updater beta
#49 (comment)
1 parent 68d6060 commit c589a3a

File tree

4 files changed

+280
-3
lines changed

4 files changed

+280
-3
lines changed

app/Http/Controllers/AdminController.php

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
use Illuminate\Support\Facades\Hash;
77
use Illuminate\Auth\Events\Registered;
88
use Illuminate\Support\Facades\Schema;
9+
use Illuminate\Support\Facades\File;
910

1011
use Auth;
1112
use Exception;
13+
use ZipArchive;
1214

1315
use App\Models\User;
1416
use App\Models\Admin;
@@ -362,6 +364,93 @@ function removeFolder($folderName) {
362364
return Redirect('/panel/theme');
363365
}}
364366

367+
// Update themes
368+
public function updateThemes()
369+
{
370+
371+
372+
if ($handle = opendir('themes')) {
373+
while (false !== ($entry = readdir($handle))) {
374+
375+
if(file_exists(base_path('themes') . '/' . $entry . '/readme.md')){
376+
$text = file_get_contents(base_path('themes') . '/' . $entry . '/readme.md');
377+
$pattern = '/Theme Version:.*/';
378+
preg_match($pattern, $text, $matches, PREG_OFFSET_CAPTURE);
379+
$verNr = substr($matches[0][0],15);}
380+
381+
$themeVe = NULL;
382+
383+
if ($entry != "." && $entry != "..") {
384+
if(file_exists(base_path('themes') . '/' . $entry . '/readme.md')){
385+
if(!strpos(file_get_contents(base_path('themes') . '/' . $entry . '/readme.md'), 'Source code:')){$hasSource = false;}else{
386+
$hasSource = true;
387+
388+
$text = file_get_contents(base_path('themes') . '/' . $entry . '/readme.md');
389+
$pattern = '/Source code:.*/';
390+
preg_match($pattern, $text, $matches, PREG_OFFSET_CAPTURE);
391+
$sourceURL = substr($matches[0][0],13);
392+
393+
$replaced = str_replace("https://github.com/", "https://api.github.com/repos/", trim($sourceURL));
394+
$replaced = $replaced . "/releases/latest";
395+
396+
if (strpos($sourceURL, 'github.com')){
397+
398+
ini_set('user_agent', 'Mozilla/4.0 (compatible; MSIE 6.0)');
399+
try{
400+
$jsont = file_get_contents($replaced);
401+
$myObjt = json_decode($jsont);
402+
$Vgitt = $myObjt->tag_name;
403+
$verNrv = 'v' . $verNr;
404+
}catch(Exception $ex){
405+
$themeVe = "error";
406+
$Vgitt = NULL;
407+
$verNrv = NULL;
408+
}
409+
410+
if(trim($Vgitt) > trim($verNrv)){
411+
412+
413+
$fileUrl = trim($sourceURL) . '/archive/refs/tags/' . trim($verNrv) . '.zip';
414+
415+
416+
file_put_contents(base_path('themes/theme.zip'), fopen($fileUrl, 'r'));
417+
418+
419+
$zip = new ZipArchive;
420+
$zip->open(base_path() . '/themes/theme.zip');
421+
$zip->extractTo(base_path('themes'));
422+
$zip->close();
423+
unlink(base_path() . '/themes/theme.zip');
424+
425+
$folder = base_path('themes');
426+
$regex = '/[0-9.-]/';
427+
$files = scandir($folder);
428+
429+
foreach($files as $file) {
430+
if($file !== '.' && $file !== '..') {
431+
if(preg_match($regex, $file)) {
432+
$new_file = preg_replace($regex, '', $file);
433+
File::copyDirectory($folder . '/' . $file, $folder . '/' . $new_file);
434+
$dirname = $folder . '/' . $file;
435+
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
436+
system('rmdir '.escapeshellarg($dirname).' /s /q');
437+
} else {
438+
system("rm -rf ".escapeshellarg($dirname));
439+
}
440+
}
441+
}
442+
}
443+
444+
}
445+
}
446+
}
447+
}
448+
}}}
449+
450+
451+
return Redirect('/studio/theme');
452+
}
453+
365454
//Shows config file editor page
366455
public function showThemes(request $request)
367456
{

app/Http/Controllers/UserController.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Auth;
99
use DB;
1010
use ZipArchive;
11+
use File;
1112

1213
use App\Models\User;
1314
use App\Models\Button;
@@ -413,8 +414,31 @@ public function editTheme(request $request)
413414
$zip->extractTo(base_path() . '/themes');
414415
$zip->close();
415416
unlink(base_path() . '/themes/temp.zip');
417+
418+
// Removes version numbers from folder.
419+
420+
$folder = base_path('themes');
421+
$regex = '/[0-9.-]/';
422+
$files = scandir($folder);
423+
424+
foreach($files as $file) {
425+
if($file !== '.' && $file !== '..') {
426+
if(preg_match($regex, $file)) {
427+
$new_file = preg_replace($regex, '', $file);
428+
File::copyDirectory($folder . '/' . $file, $folder . '/' . $new_file);
429+
$dirname = $folder . '/' . $file;
430+
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
431+
system('rmdir '.escapeshellarg($dirname).' /s /q');
432+
} else {
433+
system("rm -rf ".escapeshellarg($dirname));
434+
}
435+
}
436+
}
416437
}
417438

439+
}
440+
441+
418442
return Redirect('/studio/theme');
419443
}
420444

resources/views/studio/theme.blade.php

Lines changed: 166 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,172 @@
3838
</details>
3939

4040
@if(auth()->user()->role == 'admin')
41+
42+
<style>
43+
details {
44+
width: 65%;
45+
margin-left: 15px;
46+
{{-- max-width: calc(100% - 20rem); --}}
47+
position: relative;
48+
border: 1px solid #78909C;
49+
border-radius: 6px;
50+
background-color: #ECEFF1;
51+
color: #263238;
52+
transition: background-color .15s;
53+
54+
> :last-child {
55+
margin-bottom: 1rem;
56+
}
57+
58+
&::before {
59+
width: 100%;
60+
height: 100%;
61+
content: '';
62+
position: absolute;
63+
top: 0;
64+
left: 0;
65+
border-radius: inherit;
66+
opacity: .15;
67+
box-shadow: 0 .25em .5em #263238;
68+
pointer-events: none;
69+
transition: opacity .2s;
70+
z-index: -1;
71+
}
72+
73+
&[open] {
74+
background-color: #FFF;
75+
76+
&::before {
77+
opacity: .6;
78+
}
79+
}
80+
}
81+
82+
summary {
83+
padding: 0.375rem 0.75rem;
84+
width: 100%;
85+
display: block;
86+
position: relative;
87+
font-size: 1.33em;
88+
font-weight: bold;
89+
cursor: pointer;
90+
91+
&::before,
92+
&::after {
93+
width: .75em;
94+
height: 2px;
95+
position: absolute;
96+
top: 50%;
97+
right: 0;
98+
content: '';
99+
background-color: currentColor;
100+
text-align: right;
101+
transform: translateY(-50%);
102+
transition: transform .2s ease-in-out;
103+
}
104+
105+
&::after {
106+
transform: translateY(-50%) rotate(90deg);
107+
108+
[open] & {
109+
transform: translateY(-50%) rotate(180deg);
110+
}
111+
}
112+
113+
&::-webkit-details-marker {
114+
display: none;
115+
}
116+
}
117+
table, th, td {
118+
border:1px solid black;
119+
}
120+
</style>
121+
<br><br><br>
122+
<details>
123+
<summary><i class="bi bi-caret-down-fill"></i> Theme updater <img src="https://img.shields.io/static/v1?label=&message=BETA&color=yellow"></summary>
124+
<div style="padding:10px;">
125+
<table>
126+
<tr>
127+
<th style="width:85%;">Theme name:</th>
128+
<th style="width: 15%;">Update status:</th>
129+
<th>Version:</th>
130+
</tr>
131+
<?php
132+
133+
if ($handle = opendir('themes')) {
134+
while (false !== ($entry = readdir($handle))) {
135+
136+
if(file_exists(base_path('themes') . '/' . $entry . '/readme.md')){
137+
$text = file_get_contents(base_path('themes') . '/' . $entry . '/readme.md');
138+
$pattern = '/Theme Version:.*/';
139+
preg_match($pattern, $text, $matches, PREG_OFFSET_CAPTURE);
140+
$verNr = substr($matches[0][0],15);}
141+
142+
$themeVe = NULL;
143+
$GLOBALS['updateAv'] = NULL;
144+
145+
if ($entry != "." && $entry != "..") {
146+
echo '<tr>';
147+
echo '<th>'; print_r(ucfirst($entry));
148+
echo '</th>';
149+
echo '<th><center>';
150+
if(file_exists(base_path('themes') . '/' . $entry . '/readme.md')){
151+
if(!strpos(file_get_contents(base_path('themes') . '/' . $entry . '/readme.md'), 'Source code:')){$hasSource = false;}else{
152+
$hasSource = true;
153+
154+
$text = file_get_contents(base_path('themes') . '/' . $entry . '/readme.md');
155+
$pattern = '/Source code:.*/';
156+
preg_match($pattern, $text, $matches, PREG_OFFSET_CAPTURE);
157+
$sourceURL = substr($matches[0][0],13);
158+
159+
$replaced = str_replace("https://github.com/", "https://api.github.com/repos/", trim($sourceURL));
160+
$replaced = $replaced . "/releases/latest";
161+
162+
if (strpos($sourceURL, 'github.com')){
163+
164+
ini_set('user_agent', 'Mozilla/4.0 (compatible; MSIE 6.0)');
165+
try{
166+
$jsont = file_get_contents($replaced);
167+
$myObjt = json_decode($jsont);
168+
$Vgitt = $myObjt->tag_name;
169+
$verNrv = 'v' . $verNr;
170+
}catch(Exception $ex){
171+
$themeVe = "error";
172+
$Vgitt = NULL;
173+
$verNrv = NULL;
174+
}
175+
176+
if(trim($Vgitt) > trim($verNrv)){
177+
$updateAv = true;
178+
$GLOBALS['updateAv'] = true;
179+
} else {
180+
$updateAv = false;
181+
}
182+
} else {$themeVe = "error";}
183+
184+
}
185+
}
186+
187+
if ($themeVe == "error") {
188+
echo '<img style="scale:0.9" src="https://img.shields.io/static/v1?label=&message=Error!&color=red">';
189+
} elseif ($hasSource == false) {
190+
echo '<img style="scale:0.9" src="https://img.shields.io/static/v1?label=&message=Update manually&color=red">';
191+
} elseif($updateAv == true) {
192+
echo '<img style="scale:0.9" src="https://img.shields.io/static/v1?label=&message=Update available&color=yellow">';
193+
} else {
194+
echo '<img style="scale:0.9" src="https://img.shields.io/static/v1?label=&message=Up to date&color=green">';
195+
}
196+
echo '</center></th>';
197+
echo '<th>' . $verNr . '</th>';
198+
echo '</tr>';}
199+
}} ?>
200+
</table>
201+
</div>
202+
<a href="{{url('update/theme')}}" class="mt-3 ml-3 btn btn-info">Update themes</a><br><br>
203+
</details>
204+
205+
@if($GLOBALS['updateAv'] == true)<img style="padding-left:40px; padding-top:15px; scale: 1.5;" src="https://img.shields.io/static/v1?label=&message=A theme needs updating&color=brightgreen">@endif
206+
41207
<br><br><br>
42208
<form action="{{ route('editTheme') }}" enctype="multipart/form-data" method="post">
43209
@csrf
@@ -60,11 +226,8 @@
60226
</div>
61227
</form>
62228
</details>
63-
64-
65229

66230
@endif
67231

68-
69232
@endforeach
70233
@endsection

routes/web.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@
126126
Route::get('/panel/backups', [AdminController::class, 'showBackups'])->name('showBackups');
127127
Route::post('/panel/theme', [AdminController::class, 'deleteTheme'])->name('deleteTheme');
128128
Route::get('/panel/theme', [AdminController::class, 'showThemes'])->name('showThemes');
129+
Route::get('/update/theme', [AdminController::class, 'updateThemes'])->name('updateThemes');
129130
Route::get('/update', function () {return view('update', []);});
130131
Route::get('/backup', function () {return view('backup', []);});
131132

0 commit comments

Comments
 (0)