Passed
Push — main ( 1b574d...80523d )
by Julian
04:23
created

UserController::littlelinkhome()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 35
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 20
c 1
b 0
f 0
nc 6
nop 1
dl 0
loc 35
rs 8.9777
1
<?php
2
3
namespace App\Http\Controllers;
4
5
use Illuminate\Http\Request;
6
use Illuminate\Support\Facades\Hash;
7
use Cohensive\OEmbed\Facades\OEmbed;
8
use Illuminate\Support\Facades\Schema;
9
use Illuminate\Support\Facades\Route;
10
use Illuminate\Support\Facades\Response;
11
use JeroenDesloovere\VCard\VCard;
12
use Illuminate\Validation\Rule;
13
use Illuminate\Support\Facades\Validator;
14
use Illuminate\Support\Facades\Mail;
15
use App\Mail\ReportSubmissionMail;
16
use GeoSot\EnvEditor\Facades\EnvEditor;
17
18
use Auth;
19
use DB;
20
use ZipArchive;
21
use File;
22
23
use App\Models\User;
24
use App\Models\Button;
25
use App\Models\Link;
26
use App\Models\LinkType;
27
use App\Models\UserData;
28
29
30
//Function tests if string starts with certain string (used to test for illegal strings)
31
function stringStartsWith($haystack, $needle, $case = true)
32
{
33
    if ($case) {
34
        return strpos($haystack, $needle, 0) === 0;
35
    }
36
    return stripos($haystack, $needle, 0) === 0;
37
}
38
39
//Function tests if string ends with certain string (used to test for illegal strings)
40
function stringEndsWith($haystack, $needle, $case = true)
41
{
42
    $expectedPosition = strlen($haystack) - strlen($needle);
43
    if ($case) {
44
        return strrpos($haystack, $needle, 0) === $expectedPosition;
45
    }
46
    return strripos($haystack, $needle, 0) === $expectedPosition;
47
}
48
49
class UserController extends Controller
50
{
51
52
    //Statistics of the number of clicks and links
53
    public function index()
54
    {
55
        $userId = Auth::user()->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
56
57
        $littlelink_name = Auth::user()->littlelink_name;
0 ignored issues
show
Bug introduced by
Accessing littlelink_name on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
58
        $userinfo = User::find($userId);
59
60
        $links = Link::where('user_id', $userId)->select('link')->count();
61
        $clicks = Link::where('user_id', $userId)->sum('click_number');
62
        $topLinks = Link::where('user_id', $userId)->orderby('click_number', 'desc')
63
            ->whereNotNull('link')->where('link', '<>', '')
64
            ->take(5)->get();
65
66
        $pageStats = [
67
            'visitors' => [
68
                'all' => visits('App\Models\User', $littlelink_name)->count(),
69
                'day' => visits('App\Models\User', $littlelink_name)->period('day')->count(),
70
                'week' => visits('App\Models\User', $littlelink_name)->period('week')->count(),
71
                'month' => visits('App\Models\User', $littlelink_name)->period('month')->count(),
72
                'year' => visits('App\Models\User', $littlelink_name)->period('year')->count(),
73
            ],
74
            'os' => visits('App\Models\User', $littlelink_name)->operatingSystems(),
75
            'referers' => visits('App\Models\User', $littlelink_name)->refs(),
76
            'countries' => visits('App\Models\User', $littlelink_name)->countries(),
77
        ];
78
79
80
81
        return view('studio/index', ['greeting' => $userinfo->name, 'toplinks' => $topLinks, 'links' => $links, 'clicks' => $clicks, 'pageStats' => $pageStats]);
82
    }
83
84
    //Show littlelink page. example => http://127.0.0.1:8000/+admin
85
    public function littlelink(request $request)
86
    {
87
        if(isset($request->useif)){
88
            $littlelink_name = User::select('littlelink_name')->where('id', $request->littlelink)->value('littlelink_name');
89
            $id = $request->littlelink;
90
        } else {
91
            $littlelink_name = $request->littlelink;
92
            $id = User::select('id')->where('littlelink_name', $littlelink_name)->value('id');
93
        }
94
95
        if (empty($id)) {
96
            return abort(404);
0 ignored issues
show
Bug introduced by
Are you sure the usage of abort(404) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
97
        }
98
     
99
        $userinfo = User::select('id', 'name', 'littlelink_name', 'littlelink_description', 'theme', 'role', 'block')->where('id', $id)->first();
100
        $information = User::select('name', 'littlelink_name', 'littlelink_description', 'theme')->where('id', $id)->get();
101
        
102
        if ($userinfo->block == 'yes') {
0 ignored issues
show
Bug introduced by
The property block does not seem to exist on Illuminate\Database\Eloq...Relations\HasOneThrough.
Loading history...
Bug introduced by
The property block does not seem to exist on Illuminate\Database\Eloq...elations\HasManyThrough.
Loading history...
103
            return abort(404);
0 ignored issues
show
Bug introduced by
Are you sure the usage of abort(404) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
104
        }
105
        
106
        $links = DB::table('links')
107
        ->join('buttons', 'buttons.id', '=', 'links.button_id')
108
        ->select('links.*', 'buttons.name') // Assuming 'links.*' to fetch all columns including 'type_params'
109
        ->where('user_id', $id)
110
        ->orderBy('up_link', 'asc')
111
        ->orderBy('order', 'asc')
112
        ->get();
113
114
        // Loop through each link to decode 'type_params' and merge it into the link object
115
        foreach ($links as $link) {
116
            if (!empty($link->type_params)) {
117
                // Decode the JSON string into an associative array
118
                $typeParams = json_decode($link->type_params, true);
119
                if (is_array($typeParams)) {
120
                    // Merge the associative array into the link object
121
                    foreach ($typeParams as $key => $value) {
122
                        $link->$key = $value;
123
                    }
124
                }
125
            }
126
        }
127
128
        return view('linkstack.linkstack', ['userinfo' => $userinfo, 'information' => $information, 'links' => $links, 'littlelink_name' => $littlelink_name]);
129
    }
130
131
    //Show littlelink page as home page if set in config
132
    public function littlelinkhome(request $request)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

132
    public function littlelinkhome(/** @scrutinizer ignore-unused */ request $request)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
133
    {
134
        $littlelink_name = env('HOME_URL');
135
        $id = User::select('id')->where('littlelink_name', $littlelink_name)->value('id');
136
137
        if (empty($id)) {
138
            return abort(404);
0 ignored issues
show
Bug introduced by
Are you sure the usage of abort(404) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
139
        }
140
     
141
        $userinfo = User::select('id', 'name', 'littlelink_name', 'littlelink_description', 'theme', 'role', 'block')->where('id', $id)->first();
142
        $information = User::select('name', 'littlelink_name', 'littlelink_description', 'theme')->where('id', $id)->get();
143
        
144
        $links = DB::table('links')
145
        ->join('buttons', 'buttons.id', '=', 'links.button_id')
146
        ->select('links.*', 'buttons.name') // Assuming 'links.*' to fetch all columns including 'type_params'
147
        ->where('user_id', $id)
148
        ->orderBy('up_link', 'asc')
149
        ->orderBy('order', 'asc')
150
        ->get();
151
152
        // Loop through each link to decode 'type_params' and merge it into the link object
153
        foreach ($links as $link) {
154
            if (!empty($link->type_params)) {
155
                // Decode the JSON string into an associative array
156
                $typeParams = json_decode($link->type_params, true);
157
                if (is_array($typeParams)) {
158
                    // Merge the associative array into the link object
159
                    foreach ($typeParams as $key => $value) {
160
                        $link->$key = $value;
161
                    }
162
                }
163
            }
164
        }
165
166
        return view('linkstack.linkstack', ['userinfo' => $userinfo, 'information' => $information, 'links' => $links, 'littlelink_name' => $littlelink_name]);
167
    }
168
169
    //Redirect to user page
170
    public function userRedirect(request $request)
171
    {
172
        $id = $request->id;
173
        $user = User::select('littlelink_name')->where('id', $id)->value('littlelink_name');
174
175
        if (empty($id)) {
176
            return abort(404);
0 ignored issues
show
Bug introduced by
Are you sure the usage of abort(404) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
177
        }
178
     
179
        if (empty($user)) {
180
            return abort(404);
0 ignored issues
show
Bug introduced by
Are you sure the usage of abort(404) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
181
        }
182
183
        return redirect(url('@'.$user));
184
    }
185
186
    //Show add/update form
187
    public function AddUpdateLink($id = 0)
188
    {
189
        $linkData = $id ? Link::find($id) : new Link(['typename' => 'link', 'id' => '0']);
190
    
191
        $data = [
192
            'LinkTypes' => LinkType::get(),
193
            'LinkData' => $linkData,
194
            'LinkID' => $id,
195
            'linkTypeID' => "predefined",
196
            'title' => "Predefined Site",
197
        ];
198
199
        $data['typename'] = $linkData->type ?? 'predefined';
200
    
201
        return view('studio/edit-link', $data);
202
    }
203
204
    //Save add link
205
    public function saveLink(Request $request)
206
    {
207
        // Step 1: Validate Request
208
        // $request->validate([
209
        //     'link' => 'sometimes|url',
210
        // ]);
211
    
212
        // Step 2: Determine Link Type and Title
213
        $linkType = LinkType::findByTypename($request->typename);
214
        $LinkTitle = $request->title;
215
        $LinkURL = $request->link;
216
217
        // Step 3: Load Link Type Logic
218
        if($request->typename == 'predefined' || $request->typename == 'link') {
219
            // Determine button id based on whether a custom or predefined button is used
220
            $button_id = ($request->typename == 'link') ? ($request->GetSiteIcon == 1 ? 2 : 1) : null;
221
            $button = ($request->typename != 'link') ? Button::where('name', $request->button)->first() : null;
222
223
            $linkData = [
224
                'link' => $LinkURL,
225
                'title' => $LinkTitle ?? $button?->alt,
0 ignored issues
show
Bug introduced by
The property alt does not seem to exist on Illuminate\Database\Eloq...Relations\HasOneThrough.
Loading history...
Bug introduced by
The property alt does not seem to exist on Illuminate\Database\Eloq...elations\HasManyThrough.
Loading history...
226
                'user_id' => Auth::user()->id,
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
227
                'button_id' => $button?->id ?? $button_id,
0 ignored issues
show
Bug introduced by
The property id does not seem to exist on Illuminate\Database\Eloq...elations\HasManyThrough.
Loading history...
Bug introduced by
The property id does not seem to exist on Illuminate\Database\Eloq...Relations\HasOneThrough.
Loading history...
228
                'type' => $request->typename // Save the link type
229
            ];
230
        } else {
231
            $linkTypePath = base_path("blocks/{$linkType->typename}/handler.php");
0 ignored issues
show
Bug introduced by
The property typename does not seem to exist on App\Models\LinkType. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
232
            if (file_exists($linkTypePath)) {
233
                include $linkTypePath;
234
                $result = handleLinkType($request, $linkType);
235
                
236
                // Extract rules and linkData from the result
237
                $rules = $result['rules'];
238
                $linkData = $result['linkData'];
239
            
240
                // Validate the request
241
                $validator = Validator::make($request->all(), $rules);
242
243
                // Check if validation fails
244
                if ($validator->fails()) {
245
                    return back()->withErrors($validator)->withInput();
246
                }
247
248
                $linkData['button_id'] = $linkData['button_id'] ?? 1; // Set 'button_id' unless overwritten by handleLinkType
249
                $linkData['type'] = $linkType->typename; // Ensure 'type' is included in $linkData
250
            } else {
251
                abort(404, "Link type logic not found.");
252
            }
253
        }   
254
255
        // Step 4: Handle Custom Parameters
256
        // (Same as before)
257
258
        // Step 5: User and Button Information
259
        $userId = Auth::user()->id;
260
        $button = Button::where('name', $request->button)->first();
261
        if ($button && empty($LinkTitle)) $LinkTitle = $button->alt;
0 ignored issues
show
Unused Code introduced by
The assignment to $LinkTitle is dead and can be removed.
Loading history...
262
263
        // Step 6: Prepare Link Data
264
        // (Handled by the included file)
265
266
        // Step 7: Save or Update Link
267
        $OrigLink = Link::find($request->linkid);
268
        $linkColumns = Schema::getColumnListing('links'); // Get all column names of links table
269
        $filteredLinkData = array_intersect_key($linkData, array_flip($linkColumns)); // Filter $linkData to only include keys that are columns in the links table
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $linkData does not seem to be defined for all execution paths leading up to this point.
Loading history...
270
271
        // Combine remaining variables into one array and convert to JSON for the type_params column
272
        $customParams = array_diff_key($linkData, $filteredLinkData);
273
274
            // Check if $linkType->custom_html is defined and not null
275
            if (isset($linkType->custom_html)) {
276
                // Add $linkType->custom_html to the $customParams array
277
                $customParams['custom_html'] = $linkType->custom_html;
0 ignored issues
show
Bug introduced by
The property custom_html does not seem to exist on App\Models\LinkType. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
278
            }
279
280
            // Check if $linkType->ignore_container is defined and not null
281
            if (isset($linkType->ignore_container)) {
282
                // Add $linkType->ignore_container to the $customParams array
283
                $customParams['ignore_container'] = $linkType->ignore_container;
0 ignored issues
show
Bug introduced by
The property ignore_container does not seem to exist on App\Models\LinkType. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
284
            }
285
286
            // Check if $linkType->include_libraries is defined and not null
287
            if (isset($linkType->include_libraries)) {
288
                // Add $linkType->include_libraries to the $customParams array
289
                $customParams['include_libraries'] = $linkType->include_libraries;
0 ignored issues
show
Bug introduced by
The property include_libraries does not seem to exist on App\Models\LinkType. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
290
            }
291
        
292
        $filteredLinkData['type_params'] = json_encode($customParams);
293
294
        if ($OrigLink) {
295
            $currentValues = $OrigLink->getAttributes();
296
            $nonNullFilteredLinkData = array_filter($filteredLinkData, function($value) {return !is_null($value);});
297
            $updatedValues = array_merge($currentValues, $nonNullFilteredLinkData);
298
            $OrigLink->update($updatedValues);
299
            $message = "Link updated";
300
        } else {
301
            $link = new Link($filteredLinkData);
302
            $link->user_id = $userId;
303
            $link->save();
304
            $message = "Link added";
305
        }
306
307
        // Step 8: Redirect
308
        $redirectUrl = $request->input('param') == 'add_more' ? 'studio/add-link' : 'studio/links';
309
        return Redirect($redirectUrl)->with('success', $message);
310
    }
311
    
312
    public function sortLinks(Request $request)
313
    {
314
        $linkOrders  = $request->input("linkOrders", []);
315
        $currentPage = $request->input("currentPage", 1);
316
        $perPage     = $request->input("perPage", 0);
317
318
        if ($perPage == 0) {
319
            $currentPage = 1;
320
        }
321
322
        $linkOrders = array_unique(array_filter($linkOrders));
323
        if (!$linkOrders || $currentPage < 1) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $linkOrders of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
324
            return response()->json([
325
                'status' => 'ERROR',
326
            ]);
327
        }
328
329
        $newOrder = $perPage * ($currentPage - 1);
330
        $linkNewOrders = [];
331
        foreach ($linkOrders as $linkId) {
332
            if ($linkId < 0) {
333
                continue;
334
            }
335
336
            $linkNewOrders[$linkId] = $newOrder;
337
            Link::where("id", $linkId)
338
                ->update([
339
                    'order' => $newOrder
340
                ]);
341
            $newOrder++;
342
        }
343
344
        return response()->json([
345
            'status' => 'OK',
346
            'linkOrders' => $linkNewOrders,
347
        ]);
348
    }
349
350
351
    //Count the number of clicks and redirect to link
352
    public function clickNumber(request $request)
353
    {
354
        $linkId = $request->id;
355
356
        if (substr($linkId, -1) == '+') {
357
            $linkWithoutPlus = str_replace('+', '', $linkId);
358
            return redirect(url('info/'.$linkWithoutPlus));
359
        }
360
    
361
        $link = Link::find($linkId);
362
363
        if (empty($link)) {
364
            return abort(404);
0 ignored issues
show
Bug introduced by
Are you sure the usage of abort(404) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
365
        }
366
367
        $link = $link->link;
368
369
        if (empty($linkId)) {
370
            return abort(404);
0 ignored issues
show
Bug introduced by
Are you sure the usage of abort(404) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
371
        }
372
373
        Link::where('id', $linkId)->increment('click_number', 1);
374
375
        $response = redirect()->away($link);
376
        $response->header('X-Robots-Tag', 'noindex, nofollow');
377
378
        return $response;
379
    }
380
381
    //Download Vcard
382
    public function vcard(request $request)
383
    {
384
        $linkId = $request->id;
385
386
        // Find the link with the specified ID
387
        $link = Link::findOrFail($linkId);
388
389
        $json = $link->link;
390
391
        // Decode the JSON to a PHP array
392
        $data = json_decode($json, true);
393
        
394
        // Create a new vCard object
395
        $vcard = new VCard();
396
        
397
        // Set the vCard properties from the $data array
398
        $vcard->addName($data['last_name'], $data['first_name'], $data['middle_name'], $data['prefix'], $data['suffix']);
399
        $vcard->addCompany($data['organization']);
400
        $vcard->addJobtitle($data['vtitle']);
401
        $vcard->addRole($data['role']);
402
        $vcard->addEmail($data['email']);
403
        $vcard->addEmail($data['work_email'], 'WORK');
404
        $vcard->addURL($data['work_url'], 'WORK');
405
        $vcard->addPhoneNumber($data['home_phone'], 'HOME');
406
        $vcard->addPhoneNumber($data['work_phone'], 'WORK');
407
        $vcard->addPhoneNumber($data['cell_phone'], 'CELL');
408
        $vcard->addAddress($data['home_address_street'], '', $data['home_address_city'], $data['home_address_state'], $data['home_address_zip'], $data['home_address_country'], 'HOME');
409
        $vcard->addAddress($data['work_address_street'], '', $data['work_address_city'], $data['work_address_state'], $data['work_address_zip'], $data['work_address_country'], 'WORK');
410
        
411
412
        // $vcard->addPhoto(base_path('img/1.png'));
413
        
414
        // Generate the vCard file contents
415
        $file_contents = $vcard->getOutput();
416
        
417
        // Set the file headers for download
418
        $headers = [
419
            'Content-Type' => 'text/x-vcard',
420
            'Content-Disposition' => 'attachment; filename="contact.vcf"'
421
        ];
422
        
423
        Link::where('id', $linkId)->increment('click_number', 1);
424
425
        // Return the file download response
426
        return response()->make($file_contents, 200, $headers);
427
428
    }
429
430
    //Show link, click number, up link in links page
431
    public function showLinks()
432
    {
433
        $userId = Auth::user()->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
434
        $data['pagePage'] = 10;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.
Loading history...
435
        
436
        $data['links'] = Link::select()->where('user_id', $userId)->orderBy('up_link', 'asc')->orderBy('order', 'asc')->paginate(99999);
437
        return view('studio/links', $data);
438
    }
439
440
    //Delete link
441
    public function deleteLink(request $request)
442
    {
443
        $linkId = $request->id;
444
445
        Link::where('id', $linkId)->delete();
446
447
        $directory = base_path("assets/favicon/icons");
448
        $files = scandir($directory);
449
        foreach($files as $file) {
450
        if (strpos($file, $linkId.".") !== false) {
451
        $pathinfo = pathinfo($file, PATHINFO_EXTENSION);}}
452
        if (isset($pathinfo)) {
453
        try{File::delete(base_path("assets/favicon/icons")."/".$linkId.".".$pathinfo);} catch (exception $e) {}
0 ignored issues
show
introduced by
Consider moving this CATCH statement to a new line.
Loading history...
Bug introduced by
The type App\Http\Controllers\exception was not found. Did you mean exception? If so, make sure to prefix the type with \.
Loading history...
454
        }
455
456
        return redirect('/studio/links');
457
    }
458
459
    //Delete icon
460
    public function clearIcon(request $request)
461
    {
462
        $linkId = $request->id;
463
464
        $directory = base_path("assets/favicon/icons");
465
        $files = scandir($directory);
466
        foreach($files as $file) {
467
        if (strpos($file, $linkId.".") !== false) {
468
        $pathinfo = pathinfo($file, PATHINFO_EXTENSION);}}
469
        if (isset($pathinfo)) {
470
        try{File::delete(base_path("assets/favicon/icons")."/".$linkId.".".$pathinfo);} catch (exception $e) {}
0 ignored issues
show
introduced by
Consider moving this CATCH statement to a new line.
Loading history...
471
        }
472
473
        return redirect('/studio/links');
474
    }
475
476
    //Raise link on the littlelink page
477
    public function upLink(request $request)
478
    {
479
        $linkId = $request->id;
480
        $upLink = $request->up;
481
482
        if ($upLink == 'yes') {
483
            $up = 'no';
484
        } elseif ($upLink == 'no') {
485
            $up = 'yes';
486
        }
487
488
        Link::where('id', $linkId)->update(['up_link' => $up]);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $up does not seem to be defined for all execution paths leading up to this point.
Loading history...
489
490
        return back();
491
    }
492
493
    //Show link to edit
494
    public function showLink(request $request)
495
    {
496
        $linkId = $request->id;
497
498
        $link = Link::where('id', $linkId)->value('link');
499
        $title = Link::where('id', $linkId)->value('title');
500
        $order = Link::where('id', $linkId)->value('order');
501
        $custom_css = Link::where('id', $linkId)->value('custom_css');
502
        $buttonId = Link::where('id', $linkId)->value('button_id');
503
        $buttonName = Button::where('id', $buttonId)->value('name');
504
505
        $buttons = Button::select('id', 'name')->orderBy('name', 'asc')->get();
506
507
        return view('studio/edit-link', ['custom_css' => $custom_css, 'buttonId' => $buttonId, 'buttons' => $buttons, 'link' => $link, 'title' => $title, 'order' => $order, 'id' => $linkId, 'buttonName' => $buttonName]);
508
    }
509
510
    //Show custom CSS + custom icon
511
    public function showCSS(request $request)
512
    {
513
        $linkId = $request->id;
514
515
        $link = Link::where('id', $linkId)->value('link');
516
        $title = Link::where('id', $linkId)->value('title');
517
        $order = Link::where('id', $linkId)->value('order');
518
        $custom_css = Link::where('id', $linkId)->value('custom_css');
519
        $custom_icon = Link::where('id', $linkId)->value('custom_icon');
520
        $buttonId = Link::where('id', $linkId)->value('button_id');
521
522
        $buttons = Button::select('id', 'name')->get();
523
524
        return view('studio/button-editor', ['custom_icon' => $custom_icon, 'custom_css' => $custom_css, 'buttonId' => $buttonId, 'buttons' => $buttons, 'link' => $link, 'title' => $title, 'order' => $order, 'id' => $linkId]);
525
    }
526
527
    //Save edit link
528
    public function editLink(request $request)
529
    {
530
        $request->validate([
531
            'link' => 'required|exturl',
532
            'title' => 'required',
533
            'button' => 'required',
534
        ]);
535
536
        if (stringStartsWith($request->link, 'http://') == 'true' or stringStartsWith($request->link, 'https://') == 'true' or stringStartsWith($request->link, 'mailto:') == 'true')
537
            $link1 = $request->link;
538
        else
539
            $link1 = 'https://' . $request->link;
540
        if (stringEndsWith($request->link, '/') == 'true')
541
            $link = rtrim($link1, "/ ");
542
        else
543
        $link = $link1;
544
        $title = $request->title;
545
        $order = $request->order;
546
        $button = $request->button;
547
        $linkId = $request->id;
548
549
        $buttonId = Button::select('id')->where('name', $button)->value('id');
550
551
        Link::where('id', $linkId)->update(['link' => $link, 'title' => $title, 'order' => $order, 'button_id' => $buttonId]);
552
553
        return redirect('/studio/links');
554
    }
555
556
    //Save edit custom CSS + custom icon
557
    public function editCSS(request $request)
558
    {
559
        $linkId = $request->id;
560
        $custom_icon = $request->custom_icon;
561
        $custom_css = $request->custom_css;
562
563
        if ($request->custom_css == "" and $request->custom_icon = !"") {
0 ignored issues
show
Bug introduced by
The property custom_icon does not seem to exist on Illuminate\Http\Request.
Loading history...
564
            Link::where('id', $linkId)->update(['custom_icon' => $custom_icon]);
565
        } elseif ($request->custom_icon == "" and $request->custom_css = !"") {
0 ignored issues
show
Bug introduced by
The property custom_css does not seem to exist on Illuminate\Http\Request.
Loading history...
566
            Link::where('id', $linkId)->update(['custom_css' => $custom_css]);
567
        } else {
568
            Link::where('id', $linkId)->update([]);
569
        }
570
        return Redirect('#result');
571
    }
572
573
    //Show littlelinke page for edit
574
    public function showPage(request $request)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

574
    public function showPage(/** @scrutinizer ignore-unused */ request $request)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
575
    {
576
        $userId = Auth::user()->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
577
578
        $data['pages'] = User::where('id', $userId)->select('littlelink_name', 'littlelink_description', 'image', 'name')->get();
0 ignored issues
show
Comprehensibility Best Practice introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.
Loading history...
579
580
        return view('/studio/page', $data);
581
    }
582
583
    //Save littlelink page (name, description, logo)
584
    public function editPage(Request $request)
585
    {
586
        $userId = Auth::user()->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
587
        $littlelink_name = Auth::user()->littlelink_name;
0 ignored issues
show
Bug introduced by
Accessing littlelink_name on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
588
    
589
        $validator = Validator::make($request->all(), [
590
            'littlelink_name' => [
591
                'sometimes',
592
                'max:255',
593
                'string',
594
                'isunique:users,id,'.$userId,
595
            ],
596
            'name' => 'sometimes|max:255|string',
597
            'image' => 'sometimes|image|mimes:jpeg,jpg,png,webp|max:2048', // Max file size: 2MB
598
        ], [
599
            'littlelink_name.unique' => __('messages.That handle has already been taken'),
600
            'image.image' => __('messages.The selected file must be an image'),
601
            'image.mimes' => __('messages.The image must be') . ' JPEG, JPG, PNG, webP.',
602
            'image.max' => __('messages.The image size should not exceed 2MB'),
603
        ]);
604
    
605
        if ($validator->fails()) {
606
            return redirect('/studio/page')->withErrors($validator)->withInput();
607
        }
608
    
609
        $profilePhoto = $request->file('image');
610
        $pageName = $request->littlelink_name;
611
        $pageDescription = strip_tags($request->pageDescription, '<a><p><strong><i><ul><ol><li><blockquote><h2><h3><h4>');
612
        $pageDescription = preg_replace("/<a([^>]*)>/i", "<a $1 rel=\"noopener noreferrer nofollow\">", $pageDescription);
613
        $pageDescription = strip_tags_except_allowed_protocols($pageDescription);
614
        $name = $request->name;
615
        $checkmark = $request->checkmark;
616
        $sharebtn = $request->sharebtn;
617
        $tablinks = $request->tablinks;
618
619
        if(env('HOME_URL') !== '' && $pageName != $littlelink_name && $littlelink_name == env('HOME_URL')){
620
            EnvEditor::editKey('HOME_URL', $pageName);
621
        }
622
    
623
        User::where('id', $userId)->update([
624
            'littlelink_name' => $pageName,
625
            'littlelink_description' => $pageDescription,
626
            'name' => $name
627
        ]);
628
    
629
        if ($request->hasFile('image')) {
630
631
            // Delete the user's current avatar if it exists
632
            while (findAvatar($userId) !== "error.error") {
633
                $avatarName = findAvatar($userId);
634
                unlink(base_path($avatarName));
635
            }
636
            
637
            $fileName = $userId . '_' . time() . "." . $profilePhoto->extension();
638
            $profilePhoto->move(base_path('assets/img'), $fileName);
639
        }
640
    
641
        if ($checkmark == "on") {
642
            UserData::saveData($userId, 'checkmark', true);
643
        } else {
644
            UserData::saveData($userId, 'checkmark', false);
645
        }
646
    
647
        if ($sharebtn == "on") {
648
            UserData::saveData($userId, 'disable-sharebtn', false);
649
        } else {
650
            UserData::saveData($userId, 'disable-sharebtn', true);
651
        }
652
653
        if ($tablinks == "on") {
654
            UserData::saveData($userId, 'links-new-tab', true);
655
        } else {
656
            UserData::saveData($userId, 'links-new-tab', false);
657
        }
658
    
659
        return Redirect('/studio/page');
660
    }
661
662
    //Upload custom theme background image
663
    public function themeBackground(Request $request)
664
    {
665
        $userId = Auth::user()->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
666
        $littlelink_name = Auth::user()->littlelink_name;
0 ignored issues
show
Unused Code introduced by
The assignment to $littlelink_name is dead and can be removed.
Loading history...
Bug introduced by
Accessing littlelink_name on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
667
    
668
        $request->validate([
669
            'image' => 'required|image|mimes:jpeg,jpg,png,webp,gif|max:2048', // Max file size: 2MB
670
        ], [
671
            'image.required' => __('messages.Please select an image'),
672
            'image.image' => __('messages.The selected file must be an image'),
673
            'image.mimes' => __('messages.The image must be') . ' JPEG, JPG, PNG, webP, GIF.',
674
            'image.max' => __('messages.The image size should not exceed 2MB'),
675
        ]);
676
    
677
        $customBackground = $request->file('image');
678
    
679
        if ($customBackground) {
680
            $directory = base_path('assets/img/background-img/');
681
            $files = scandir($directory);
682
            $pathinfo = "error.error";
0 ignored issues
show
Unused Code introduced by
The assignment to $pathinfo is dead and can be removed.
Loading history...
683
            foreach ($files as $file) {
684
                if (strpos($file, $userId . '.') !== false) {
685
                    $pathinfo = $userId . "." . pathinfo($file, PATHINFO_EXTENSION);
0 ignored issues
show
Bug introduced by
Are you sure pathinfo($file, App\Http...ers\PATHINFO_EXTENSION) of type array|string can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

685
                    $pathinfo = $userId . "." . /** @scrutinizer ignore-type */ pathinfo($file, PATHINFO_EXTENSION);
Loading history...
686
                }
687
            }
688
    
689
            // Delete the user's current background image if it exists
690
            while (findBackground($userId) !== "error.error") {
691
                $avatarName = "assets/img/background-img/" . findBackground(Auth::id());
692
                unlink(base_path($avatarName));
693
            }
694
                
695
            $fileName = $userId . '_' . time() . "." . $customBackground->extension();
696
            $customBackground->move(base_path('assets/img/background-img/'), $fileName);
697
    
698
            if (extension_loaded('imagick')) {
699
                $imagePath = base_path('assets/img/background-img/') . $fileName;
700
                $image = new \Imagick($imagePath);
701
                $image->stripImage();
702
                $image->writeImage($imagePath);
703
            }
704
    
705
            return redirect('/studio/theme');
706
        }
707
    
708
        return redirect('/studio/theme')->with('error', 'Please select a valid image file.');
709
    }
710
711
    //Delete custom background image
712
    public function removeBackground()
713
    {
714
        $userId = Auth::user()->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
715
716
        // Delete the user's current background image if it exists
717
        while (findBackground($userId) !== "error.error") {
718
            $avatarName = "assets/img/background-img/" . findBackground(Auth::id());
719
            unlink(base_path($avatarName));
720
        }
721
722
        return back();
723
    }
724
725
726
    //Show custom theme
727
    public function showTheme(request $request)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

727
    public function showTheme(/** @scrutinizer ignore-unused */ request $request)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
728
    {
729
        $userId = Auth::user()->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
730
731
        $data['pages'] = User::where('id', $userId)->select('littlelink_name', 'theme')->get();
0 ignored issues
show
Comprehensibility Best Practice introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.
Loading history...
732
733
        return view('/studio/theme', $data);
734
    }
735
736
    //Save custom theme
737
    public function editTheme(request $request)
738
    {
739
        $request->validate([
740
            'zip' => 'sometimes|mimes:zip',
741
        ]);
742
743
        $userId = Auth::user()->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
744
745
        $zipfile = $request->file('zip');
746
747
        $theme = $request->theme;
748
        $message = "";
749
750
        User::where('id', $userId)->update(['theme' => $theme]);
751
752
753
754
        if (!empty($zipfile) && Auth::user()->role == 'admin') {
0 ignored issues
show
Bug introduced by
Accessing role on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
755
756
            $zipfile->move(base_path('/themes'), "temp.zip");
757
758
            $zip = new ZipArchive;
759
            $zip->open(base_path() . '/themes/temp.zip');
760
            $zip->extractTo(base_path() . '/themes');
761
            $zip->close();
762
            unlink(base_path() . '/themes/temp.zip');
763
764
            // Removes version numbers from folder.
765
766
            $folder = base_path('themes');
767
            $regex = '/[0-9.-]/';
768
            $files = scandir($folder);
769
770
            foreach ($files as $file) {
771
                $basename = basename($file);
772
                if (preg_match($regex, $basename)) {
773
                    $newBasename = preg_replace($regex, '', $basename);
774
                    $newPath = $folder . '/' . $newBasename;
775
                    File::copyDirectory($file, $newPath);
776
                    File::deleteDirectory($file);
777
                }
778
            }
779
        }
780
781
782
        return Redirect('/studio/theme')->with("success", $message);
783
    }
784
785
    //Show user (name, email, password)
786
    public function showProfile(request $request)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

786
    public function showProfile(/** @scrutinizer ignore-unused */ request $request)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
787
    {
788
        $userId = Auth::user()->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
789
790
        $data['profile'] = User::where('id', $userId)->select('name', 'email', 'role')->get();
0 ignored issues
show
Comprehensibility Best Practice introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.
Loading history...
791
792
        return view('/studio/profile', $data);
793
    }
794
795
    //Save user (name, email, password)
796
    public function editProfile(request $request)
797
    {
798
        $request->validate([
799
            'name' => 'sometimes|required|unique:users',
800
            'email' => 'sometimes|required|email|unique:users',
801
            'password' => 'sometimes|min:8',
802
        ]);
803
804
        $userId = Auth::user()->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
805
806
        $name = $request->name;
807
        $email = $request->email;
808
        $password = Hash::make($request->password);
809
810
        if ($request->name != '') {
811
            User::where('id', $userId)->update(['name' => $name]);
812
        } elseif ($request->email != '') {
813
            User::where('id', $userId)->update(['email' => $email]);
814
        } elseif ($request->password != '') {
815
            User::where('id', $userId)->update(['password' => $password]);
816
            Auth::logout();
817
        }
818
        return back();
819
    }
820
821
    //Show user theme credit page
822
    public function theme(request $request)
823
    {
824
        $littlelink_name = $request->littlelink;
825
        $id = User::select('id')->where('littlelink_name', $littlelink_name)->value('id');
826
827
        if (empty($id)) {
828
            return abort(404);
0 ignored issues
show
Bug introduced by
Are you sure the usage of abort(404) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
829
        }
830
831
        $userinfo = User::select('name', 'littlelink_name', 'littlelink_description', 'theme')->where('id', $id)->first();
832
        $information = User::select('name', 'littlelink_name', 'littlelink_description', 'theme')->where('id', $id)->get();
833
834
        $links = DB::table('links')->join('buttons', 'buttons.id', '=', 'links.button_id')->select('links.link', 'links.id', 'links.button_id', 'links.title', 'links.custom_css', 'links.custom_icon', 'buttons.name')->where('user_id', $id)->orderBy('up_link', 'asc')->orderBy('order', 'asc')->get();
835
836
        return view('components/theme', ['userinfo' => $userinfo, 'information' => $information, 'links' => $links, 'littlelink_name' => $littlelink_name]);
837
    }
838
839
    //Delete existing user
840
    public function deleteUser(request $request)
841
    {
842
843
        // echo $request->id;
844
        // echo "<br>";
845
        // echo Auth::id();
846
        $id = $request->id;
847
848
    if($id == Auth::id() and $id != "1") {
849
850
        Link::where('user_id', $id)->delete();
851
852
        $user = User::find($id);
853
854
        Schema::disableForeignKeyConstraints();
855
        $user->forceDelete();
856
        Schema::enableForeignKeyConstraints();
857
    }
858
859
        return redirect('/');
860
    }
861
862
    //Delete profile picture
863
    public function delProfilePicture()
864
    {
865
        $userId = Auth::user()->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
866
867
        // Delete the user's current avatar if it exists
868
        while (findAvatar($userId) !== "error.error") {
869
            $avatarName = findAvatar($userId);
870
            unlink(base_path($avatarName));
871
        }
872
873
        return back();
874
    }
875
876
    //Export user links
877
    public function exportLinks(request $request)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

877
    public function exportLinks(/** @scrutinizer ignore-unused */ request $request)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
878
    {
879
        $userId = Auth::id();
880
        $user = User::find($userId);
881
        $links = Link::where('user_id', $userId)->get();
882
        
883
        if (!$user) {
884
            // handle the case where the user is null
885
            return response()->json(['message' => 'User not found'], 404);
886
        }
887
888
        $userData['links'] = $links->toArray();
0 ignored issues
show
Comprehensibility Best Practice introduced by
$userData was never initialized. Although not strictly required by PHP, it is generally a good practice to add $userData = array(); before regardless.
Loading history...
889
890
        $domain = $_SERVER['HTTP_HOST'];
891
        $date = date('Y-m-d_H-i-s');
892
        $fileName = "links-$domain-$date.json";
893
        $headers = [
894
            'Content-Type' => 'application/json',
895
            'Content-Disposition' => 'attachment; filename="'.$fileName.'"',
896
        ];
897
        return response()->json($userData, 200, $headers);
898
899
        return back();
0 ignored issues
show
Unused Code introduced by
return back() is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
900
    }
901
902
    //Export all user data
903
    public function exportAll(Request $request)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

903
    public function exportAll(/** @scrutinizer ignore-unused */ Request $request)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
904
    {
905
        $userId = Auth::id();
906
        $user = User::find($userId);
907
        $links = Link::where('user_id', $userId)->get();
908
    
909
        if (!$user) {
910
            // handle the case where the user is null
911
            return response()->json(['message' => 'User not found'], 404);
912
        }
913
    
914
        $userData = $user->toArray();
915
        $userData['links'] = $links->toArray();
916
917
        if (file_exists(base_path(findAvatar($userId)))){
918
            $imagePath = base_path(findAvatar($userId));
919
            $imageData = base64_encode(file_get_contents($imagePath));
920
            $userData['image_data'] = $imageData;
921
    
922
            $imageExtension = pathinfo($imagePath, PATHINFO_EXTENSION);
923
            $userData['image_extension'] = $imageExtension;
924
        }
925
    
926
        $domain = $_SERVER['HTTP_HOST'];
927
        $date = date('Y-m-d_H-i-s');
928
        $fileName = "user_data-$domain-$date.json";
929
        $headers = [
930
            'Content-Type' => 'application/json',
931
            'Content-Disposition' => 'attachment; filename="'.$fileName.'"',
932
        ];
933
        return response()->json($userData, 200, $headers);
934
    
935
        return back();
0 ignored issues
show
Unused Code introduced by
return back() is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
936
    }    
937
938
    public function importData(Request $request)
939
    {
940
        try {
941
            // Get the JSON data from the uploaded file
942
            if (!$request->hasFile('import') || !$request->file('import')->isValid()) {
943
                throw new \Exception('File not uploaded or is faulty');
944
            }
945
            $file = $request->file('import');
946
            $jsonString = $file->get();
947
            $userData = json_decode($jsonString, true);
948
    
949
            // Update the authenticated user's profile data if defined in the JSON file
950
            $user = auth()->user();
951
            if (isset($userData['name'])) {
952
                $user->name = $userData['name'];
953
            }
954
955
            if (isset($userData['littlelink_description'])) {
956
                $sanitizedText = $userData['littlelink_description'];
957
                $sanitizedText = strip_tags($sanitizedText, '<a><p><strong><i><ul><ol><li><blockquote><h2><h3><h4>');
958
                $sanitizedText = preg_replace("/<a([^>]*)>/i", "<a $1 rel=\"noopener noreferrer nofollow\">", $sanitizedText);
959
                $sanitizedText = strip_tags_except_allowed_protocols($sanitizedText);
960
                $user->littlelink_description = $sanitizedText;
961
            }
962
963
            if (isset($userData['image_data'])) {
964
965
                $allowedExtensions = array('jpeg', 'jpg', 'png', 'webp');
966
                $userExtension = strtolower($userData['image_extension']);
967
968
                if (in_array($userExtension, $allowedExtensions)) {
969
                // Decode the image data from Base64
970
                $imageData = base64_decode($userData['image_data']);
971
972
                // Delete the user's current avatar if it exists
973
                while (findAvatar(Auth::id()) !== "error.error") {
974
                    $avatarName = findAvatar(Auth::id());
975
                    unlink(base_path($avatarName));
976
                }
977
                
978
                // Save the image to the correct path with the correct file name and extension
979
                $filename = $user->id . '.' . $userExtension;
980
                file_put_contents(base_path('assets/img/' . $filename), $imageData);
981
                
982
                // Update the user's image field with the correct file name
983
                $user->image = $filename;
984
                }
985
            }
986
987
            $user->save();
988
    
989
            // Delete all links for the authenticated user
990
            Link::where('user_id', $user->id)->delete();
991
    
992
            // Loop through each link in $userData and create a new link for the user
993
            foreach ($userData['links'] as $linkData) {
994
995
                $validatedData = Validator::make($linkData, [
996
                    'link' => 'nullable|exturl',
997
                ]);
998
999
                if ($validatedData->fails()) {
1000
                    throw new \Exception('Invalid link');
1001
                }
1002
1003
                $newLink = new Link();
1004
    
1005
                // Copy over the link data from $linkData to $newLink
1006
                $newLink->button_id = $linkData['button_id'];
1007
                $newLink->link = $linkData['link'];
1008
                
1009
                // Sanitize the title
1010
                if ($linkData['button_id'] == 93) {
1011
                    $sanitizedText = strip_tags($linkData['title'], '<a><p><strong><i><ul><ol><li><blockquote><h2><h3><h4>');
1012
                    $sanitizedText = preg_replace("/<a([^>]*)>/i", "<a $1 rel=\"noopener noreferrer nofollow\">", $sanitizedText);
1013
                    $sanitizedText = strip_tags_except_allowed_protocols($sanitizedText);
1014
                
1015
                    $newLink->title = $sanitizedText;
1016
                } else {
1017
                    $newLink->title = $linkData['title'];
1018
                }
1019
1020
                $newLink->order = $linkData['order'];
1021
                $newLink->click_number = 0;
1022
                $newLink->up_link = $linkData['up_link'];
1023
                $newLink->custom_css = $linkData['custom_css'];
1024
                $newLink->custom_icon = $linkData['custom_icon'];
1025
                $newLink->type = $linkData['type'];
1026
                $newLink->type_params = $linkData['type_params'];
1027
    
1028
                // Set the user ID to the current user's ID
1029
                $newLink->user_id = $user->id;
1030
    
1031
                // Save the new link to the database
1032
                $newLink->save();
1033
            }
1034
            return redirect('studio/profile')->with('success', __('messages.Profile updated successfully!'));
1035
        } catch (\Exception $e) {
1036
            return redirect('studio/profile')->with('error', __('messages.An error occurred while updating your profile.'));
1037
        }
1038
    }
1039
    
1040
1041
    // Hanle reports
1042
    function report(Request $request)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
1043
    {
1044
        $formData = $request->all();
1045
    
1046
        try {
1047
            Mail::to(env('ADMIN_EMAIL'))->send(new ReportSubmissionMail($formData));
1048
            
1049
            return redirect('report')->with('success', __('messages.report_success'));
1050
        } catch (\Exception $e) {
1051
            return redirect()->back()->with('error', __('messages.report_error'));
1052
        }
1053
    }
1054
1055
    //Edit/save page icons
1056
    public function editIcons(Request $request)
1057
    {
1058
        $inputKeys = array_keys($request->except('_token'));
1059
1060
        $validationRules = [];
1061
1062
        foreach ($inputKeys as $platform) {
1063
            $validationRules[$platform] = 'nullable|exturl|max:255';
1064
        }
1065
1066
        $request->validate($validationRules);
1067
1068
        foreach ($inputKeys as $platform) {
1069
            $link = $request->input($platform);
1070
1071
            if (!empty($link)) {
1072
                $iconId = $this->searchIcon($platform);
1073
1074
                if (!is_null($iconId)) {
1075
                    $this->updateIcon($platform, $link);
1076
                } else {
1077
                    $this->addIcon($platform, $link);
1078
                }
1079
            }
1080
        }
1081
1082
        return redirect('studio/links#icons');
1083
    }
1084
1085
    private function searchIcon($icon)
1086
    {
1087
        return DB::table('links')
1088
            ->where('user_id', Auth::id())
1089
            ->where('title', $icon)
1090
            ->where('button_id', 94)
1091
            ->value('id');
1092
    }
1093
1094
    private function addIcon($icon, $link)
1095
    {
1096
        $userId = Auth::user()->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
1097
        $links = new Link;
1098
        $links->link = $link;
1099
        $links->user_id = $userId;
1100
        $links->title = $icon;
1101
        $links->button_id = '94';
1102
        $links->save();
1103
        $links->order = ($links->id - 1);
1104
        $links->save();
1105
    }
1106
1107
    private function updateIcon($icon, $link)
1108
    {
1109
        Link::where('id', $this->searchIcon($icon))->update([
1110
            'button_id' => 94,
1111
            'link' => $link,
1112
            'title' => $icon
1113
        ]);
1114
    }
1115
}