Passed
Push — main ( 39ac5b...9806af )
by Julian
09:30
created

UserController::saveLink()   F

Complexity

Conditions 14
Paths 640

Size

Total Lines 92
Code Lines 48

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 1 Features 0
Metric Value
cc 14
eloc 48
c 5
b 1
f 0
nc 640
nop 1
dl 0
loc 92
rs 2.6

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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')->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();
145
146
        return view('linkstack.linkstack', ['userinfo' => $userinfo, 'information' => $information, 'links' => $links, 'littlelink_name' => $littlelink_name]);
147
    }
148
149
    //Redirect to user page
150
    public function userRedirect(request $request)
151
    {
152
        $id = $request->id;
153
        $user = User::select('littlelink_name')->where('id', $id)->value('littlelink_name');
154
155
        if (empty($id)) {
156
            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...
157
        }
158
     
159
        if (empty($user)) {
160
            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...
161
        }
162
163
        return redirect(url('@'.$user));
164
    }
165
166
    //Show add/update form
167
    public function AddUpdateLink($id = 0)
168
    {
169
        $linkData = $id ? Link::find($id) : new Link(['typename' => 'link', 'id' => '0']);
170
    
171
        $data = [
172
            'LinkTypes' => LinkType::get(),
173
            'LinkData' => $linkData,
174
            'LinkID' => $id,
175
            'linkTypeID' => "predefined",
176
            'title' => "Predefined Site",
177
        ];
178
179
        $data['typename'] = $linkData->type ?? 'predefined';
180
    
181
        return view('studio/edit-link', $data);
182
    }
183
184
    //Save add link
185
    public function saveLink(Request $request)
186
    {
187
        // Step 1: Validate Request
188
        // $request->validate([
189
        //     'link' => 'sometimes|url',
190
        // ]);
191
    
192
        // Step 2: Determine Link Type and Title
193
        $linkType = LinkType::findByTypename($request->typename);
194
        $LinkTitle = $request->title;
195
        $LinkURL = $request->link;
196
197
        // Step 3: Load Link Type Logic
198
        if($request->typename == 'predefined' || $request->typename == 'link') {
199
            // Determine button id based on whether a custom or predefined button is used
200
            $button_id = ($request->typename == 'link') ? ($request->GetSiteIcon == 1 ? 2 : 1) : null;
201
            $button = ($request->typename != 'link') ? Button::where('name', $request->button)->first() : null;
202
203
            $linkData = [
204
                'link' => $LinkURL,
205
                '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...
206
                '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...
207
                '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...Relations\HasOneThrough.
Loading history...
Bug introduced by
The property id does not seem to exist on Illuminate\Database\Eloq...elations\HasManyThrough.
Loading history...
208
                'type' => $request->typename // Save the link type
209
            ];
210
        } else {
211
            $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...
212
            if (file_exists($linkTypePath)) {
213
                include $linkTypePath;
214
                $linkData = handleLinkType($request, $linkType);
215
                $linkData['button_id'] = $linkData['button_id'] ?? 1; // Set 'button_id' unless overwritten by handleLinkType
216
                $linkData['type'] = $linkType->typename; // Ensure 'type' is included in $linkData
217
            } else {
218
                abort(404, "Link type logic not found.");
219
            }
220
        }   
221
222
        // Step 4: Handle Custom Parameters
223
        // (Same as before)
224
225
        // Step 5: User and Button Information
226
        $userId = Auth::user()->id;
227
        $button = Button::where('name', $request->button)->first();
228
        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...
229
230
        // Step 6: Prepare Link Data
231
        // (Handled by the included file)
232
233
        // Step 7: Save or Update Link
234
        $OrigLink = Link::find($request->linkid);
235
        $linkColumns = Schema::getColumnListing('links'); // Get all column names of links table
236
        $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...
237
238
        // Combine remaining variables into one array and convert to JSON for the type_params column
239
        $customParams = array_diff_key($linkData, $filteredLinkData);
240
241
            // Check if $linkType->custom_html is defined and not null
242
            if (isset($linkType->custom_html)) {
243
                // Add $linkType->custom_html to the $customParams array
244
                $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...
245
            }
246
247
            // Check if $linkType->ignore_container is defined and not null
248
            if (isset($linkType->ignore_container)) {
249
                // Add $linkType->ignore_container to the $customParams array
250
                $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...
251
            }
252
253
            // Check if $linkType->include_libraries is defined and not null
254
            if (isset($linkType->include_libraries)) {
255
                // Add $linkType->include_libraries to the $customParams array
256
                $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...
257
            }
258
        
259
        $filteredLinkData['type_params'] = json_encode($customParams);
260
261
        if ($OrigLink) {
262
            $currentValues = $OrigLink->getAttributes();
263
            $nonNullFilteredLinkData = array_filter($filteredLinkData, function($value) {return !is_null($value);});
264
            $updatedValues = array_merge($currentValues, $nonNullFilteredLinkData);
265
            $OrigLink->update($updatedValues);
266
            $message = "Link updated";
267
        } else {
268
            $link = new Link($filteredLinkData);
269
            $link->user_id = $userId;
270
            $link->save();
271
            $message = "Link added";
272
        }
273
274
        // Step 8: Redirect
275
        $redirectUrl = $request->input('param') == 'add_more' ? 'studio/add-link' : 'studio/links';
276
        return Redirect($redirectUrl)->with('success', $message);
277
    }
278
    
279
    public function sortLinks(Request $request)
280
    {
281
        $linkOrders  = $request->input("linkOrders", []);
282
        $currentPage = $request->input("currentPage", 1);
283
        $perPage     = $request->input("perPage", 0);
284
285
        if ($perPage == 0) {
286
            $currentPage = 1;
287
        }
288
289
        $linkOrders = array_unique(array_filter($linkOrders));
290
        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...
291
            return response()->json([
292
                'status' => 'ERROR',
293
            ]);
294
        }
295
296
        $newOrder = $perPage * ($currentPage - 1);
297
        $linkNewOrders = [];
298
        foreach ($linkOrders as $linkId) {
299
            if ($linkId < 0) {
300
                continue;
301
            }
302
303
            $linkNewOrders[$linkId] = $newOrder;
304
            Link::where("id", $linkId)
305
                ->update([
306
                    'order' => $newOrder
307
                ]);
308
            $newOrder++;
309
        }
310
311
        return response()->json([
312
            'status' => 'OK',
313
            'linkOrders' => $linkNewOrders,
314
        ]);
315
    }
316
317
318
    //Count the number of clicks and redirect to link
319
    public function clickNumber(request $request)
320
    {
321
        $linkId = $request->id;
322
323
        if (substr($linkId, -1) == '+') {
324
            $linkWithoutPlus = str_replace('+', '', $linkId);
325
            return redirect(url('info/'.$linkWithoutPlus));
326
        }
327
    
328
        $link = Link::find($linkId);
329
330
        if (empty($link)) {
331
            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...
332
        }
333
334
        $link = $link->link;
335
336
        if (empty($linkId)) {
337
            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...
338
        }
339
340
        Link::where('id', $linkId)->increment('click_number', 1);
341
342
        $response = redirect()->away($link);
343
        $response->header('X-Robots-Tag', 'noindex, nofollow');
344
345
        return $response;
346
    }
347
348
    //Download Vcard
349
    public function vcard(request $request)
350
    {
351
        $linkId = $request->id;
352
353
        // Find the link with the specified ID
354
        $link = Link::findOrFail($linkId);
355
356
        $json = $link->link;
357
358
        // Decode the JSON to a PHP array
359
        $data = json_decode($json, true);
360
        
361
        // Create a new vCard object
362
        $vcard = new VCard();
363
        
364
        // Set the vCard properties from the $data array
365
        $vcard->addName($data['last_name'], $data['first_name'], $data['middle_name'], $data['prefix'], $data['suffix']);
366
        $vcard->addCompany($data['organization']);
367
        $vcard->addJobtitle($data['vtitle']);
368
        $vcard->addRole($data['role']);
369
        $vcard->addEmail($data['email']);
370
        $vcard->addEmail($data['work_email'], 'WORK');
371
        $vcard->addURL($data['work_url'], 'WORK');
372
        $vcard->addPhoneNumber($data['home_phone'], 'HOME');
373
        $vcard->addPhoneNumber($data['work_phone'], 'WORK');
374
        $vcard->addPhoneNumber($data['cell_phone'], 'CELL');
375
        $vcard->addAddress($data['home_address_street'], '', $data['home_address_city'], $data['home_address_state'], $data['home_address_zip'], $data['home_address_country'], 'HOME');
376
        $vcard->addAddress($data['work_address_street'], '', $data['work_address_city'], $data['work_address_state'], $data['work_address_zip'], $data['work_address_country'], 'WORK');
377
        
378
379
        // $vcard->addPhoto(base_path('img/1.png'));
380
        
381
        // Generate the vCard file contents
382
        $file_contents = $vcard->getOutput();
383
        
384
        // Set the file headers for download
385
        $headers = [
386
            'Content-Type' => 'text/x-vcard',
387
            'Content-Disposition' => 'attachment; filename="contact.vcf"'
388
        ];
389
        
390
        Link::where('id', $linkId)->increment('click_number', 1);
391
392
        // Return the file download response
393
        return response()->make($file_contents, 200, $headers);
394
395
    }
396
397
    //Show link, click number, up link in links page
398
    public function showLinks()
399
    {
400
        $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...
401
        $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...
402
        
403
        $data['links'] = Link::select()->where('user_id', $userId)->orderBy('up_link', 'asc')->orderBy('order', 'asc')->paginate(99999);
404
        return view('studio/links', $data);
405
    }
406
407
    //Delete link
408
    public function deleteLink(request $request)
409
    {
410
        $linkId = $request->id;
411
412
        Link::where('id', $linkId)->delete();
413
414
        $directory = base_path("assets/favicon/icons");
415
        $files = scandir($directory);
416
        foreach($files as $file) {
417
        if (strpos($file, $linkId.".") !== false) {
418
        $pathinfo = pathinfo($file, PATHINFO_EXTENSION);}}
419
        if (isset($pathinfo)) {
420
        try{File::delete(base_path("assets/favicon/icons")."/".$linkId.".".$pathinfo);} catch (exception $e) {}
0 ignored issues
show
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...
introduced by
Consider moving this CATCH statement to a new line.
Loading history...
421
        }
422
423
        return redirect('/studio/links');
424
    }
425
426
    //Delete icon
427
    public function clearIcon(request $request)
428
    {
429
        $linkId = $request->id;
430
431
        $directory = base_path("assets/favicon/icons");
432
        $files = scandir($directory);
433
        foreach($files as $file) {
434
        if (strpos($file, $linkId.".") !== false) {
435
        $pathinfo = pathinfo($file, PATHINFO_EXTENSION);}}
436
        if (isset($pathinfo)) {
437
        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...
438
        }
439
440
        return redirect('/studio/links');
441
    }
442
443
    //Raise link on the littlelink page
444
    public function upLink(request $request)
445
    {
446
        $linkId = $request->id;
447
        $upLink = $request->up;
448
449
        if ($upLink == 'yes') {
450
            $up = 'no';
451
        } elseif ($upLink == 'no') {
452
            $up = 'yes';
453
        }
454
455
        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...
456
457
        return back();
458
    }
459
460
    //Show link to edit
461
    public function showLink(request $request)
462
    {
463
        $linkId = $request->id;
464
465
        $link = Link::where('id', $linkId)->value('link');
466
        $title = Link::where('id', $linkId)->value('title');
467
        $order = Link::where('id', $linkId)->value('order');
468
        $custom_css = Link::where('id', $linkId)->value('custom_css');
469
        $buttonId = Link::where('id', $linkId)->value('button_id');
470
        $buttonName = Button::where('id', $buttonId)->value('name');
471
472
        $buttons = Button::select('id', 'name')->orderBy('name', 'asc')->get();
473
474
        return view('studio/edit-link', ['custom_css' => $custom_css, 'buttonId' => $buttonId, 'buttons' => $buttons, 'link' => $link, 'title' => $title, 'order' => $order, 'id' => $linkId, 'buttonName' => $buttonName]);
475
    }
476
477
    //Show custom CSS + custom icon
478
    public function showCSS(request $request)
479
    {
480
        $linkId = $request->id;
481
482
        $link = Link::where('id', $linkId)->value('link');
483
        $title = Link::where('id', $linkId)->value('title');
484
        $order = Link::where('id', $linkId)->value('order');
485
        $custom_css = Link::where('id', $linkId)->value('custom_css');
486
        $custom_icon = Link::where('id', $linkId)->value('custom_icon');
487
        $buttonId = Link::where('id', $linkId)->value('button_id');
488
489
        $buttons = Button::select('id', 'name')->get();
490
491
        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]);
492
    }
493
494
    //Save edit link
495
    public function editLink(request $request)
496
    {
497
        $request->validate([
498
            'link' => 'required|exturl',
499
            'title' => 'required',
500
            'button' => 'required',
501
        ]);
502
503
        if (stringStartsWith($request->link, 'http://') == 'true' or stringStartsWith($request->link, 'https://') == 'true' or stringStartsWith($request->link, 'mailto:') == 'true')
504
            $link1 = $request->link;
505
        else
506
            $link1 = 'https://' . $request->link;
507
        if (stringEndsWith($request->link, '/') == 'true')
508
            $link = rtrim($link1, "/ ");
509
        else
510
        $link = $link1;
511
        $title = $request->title;
512
        $order = $request->order;
513
        $button = $request->button;
514
        $linkId = $request->id;
515
516
        $buttonId = Button::select('id')->where('name', $button)->value('id');
517
518
        Link::where('id', $linkId)->update(['link' => $link, 'title' => $title, 'order' => $order, 'button_id' => $buttonId]);
519
520
        return redirect('/studio/links');
521
    }
522
523
    //Save edit custom CSS + custom icon
524
    public function editCSS(request $request)
525
    {
526
        $linkId = $request->id;
527
        $custom_icon = $request->custom_icon;
528
        $custom_css = $request->custom_css;
529
530
        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...
531
            Link::where('id', $linkId)->update(['custom_icon' => $custom_icon]);
532
        } 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...
533
            Link::where('id', $linkId)->update(['custom_css' => $custom_css]);
534
        } else {
535
            Link::where('id', $linkId)->update([]);
536
        }
537
        return Redirect('#result');
538
    }
539
540
    //Show littlelinke page for edit
541
    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

541
    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...
542
    {
543
        $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...
544
545
        $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...
546
547
        return view('/studio/page', $data);
548
    }
549
550
    //Save littlelink page (name, description, logo)
551
    public function editPage(Request $request)
552
    {
553
        $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...
554
        $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...
555
    
556
        $validator = Validator::make($request->all(), [
557
            'littlelink_name' => [
558
                'sometimes',
559
                'max:255',
560
                'string',
561
                'isunique:users,id,'.$userId,
562
            ],
563
            'name' => 'sometimes|max:255|string',
564
            'image' => 'sometimes|image|mimes:jpeg,jpg,png,webp|max:2048', // Max file size: 2MB
565
        ], [
566
            'littlelink_name.unique' => __('messages.That handle has already been taken'),
567
            'image.image' => __('messages.The selected file must be an image'),
568
            'image.mimes' => __('messages.The image must be') . ' JPEG, JPG, PNG, webP.',
569
            'image.max' => __('messages.The image size should not exceed 2MB'),
570
        ]);
571
    
572
        if ($validator->fails()) {
573
            return redirect('/studio/page')->withErrors($validator)->withInput();
574
        }
575
    
576
        $profilePhoto = $request->file('image');
577
        $pageName = $request->littlelink_name;
578
        $pageDescription = strip_tags($request->pageDescription, '<a><p><strong><i><ul><ol><li><blockquote><h2><h3><h4>');
579
        $pageDescription = preg_replace("/<a([^>]*)>/i", "<a $1 rel=\"noopener noreferrer nofollow\">", $pageDescription);
580
        $pageDescription = strip_tags_except_allowed_protocols($pageDescription);
581
        $name = $request->name;
582
        $checkmark = $request->checkmark;
583
        $sharebtn = $request->sharebtn;
584
        $tablinks = $request->tablinks;
585
586
        if(env('HOME_URL') !== '' && $pageName != $littlelink_name && $littlelink_name == env('HOME_URL')){
587
            EnvEditor::editKey('HOME_URL', $pageName);
588
        }
589
    
590
        User::where('id', $userId)->update([
591
            'littlelink_name' => $pageName,
592
            'littlelink_description' => $pageDescription,
593
            'name' => $name
594
        ]);
595
    
596
        if ($request->hasFile('image')) {
597
598
            // Delete the user's current avatar if it exists
599
            while (findAvatar($userId) !== "error.error") {
600
                $avatarName = findAvatar($userId);
601
                unlink(base_path($avatarName));
602
            }
603
            
604
            $fileName = $userId . '_' . time() . "." . $profilePhoto->extension();
605
            $profilePhoto->move(base_path('assets/img'), $fileName);
606
        }
607
    
608
        if ($checkmark == "on") {
609
            UserData::saveData($userId, 'checkmark', true);
610
        } else {
611
            UserData::saveData($userId, 'checkmark', false);
612
        }
613
    
614
        if ($sharebtn == "on") {
615
            UserData::saveData($userId, 'disable-sharebtn', false);
616
        } else {
617
            UserData::saveData($userId, 'disable-sharebtn', true);
618
        }
619
620
        if ($tablinks == "on") {
621
            UserData::saveData($userId, 'links-new-tab', true);
622
        } else {
623
            UserData::saveData($userId, 'links-new-tab', false);
624
        }
625
    
626
        return Redirect('/studio/page');
627
    }
628
629
    //Upload custom theme background image
630
    public function themeBackground(Request $request)
631
    {
632
        $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...
633
        $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...
634
    
635
        $request->validate([
636
            'image' => 'required|image|mimes:jpeg,jpg,png,webp,gif|max:2048', // Max file size: 2MB
637
        ], [
638
            'image.required' => __('messages.Please select an image'),
639
            'image.image' => __('messages.The selected file must be an image'),
640
            'image.mimes' => __('messages.The image must be') . ' JPEG, JPG, PNG, webP, GIF.',
641
            'image.max' => __('messages.The image size should not exceed 2MB'),
642
        ]);
643
    
644
        $customBackground = $request->file('image');
645
    
646
        if ($customBackground) {
647
            $directory = base_path('assets/img/background-img/');
648
            $files = scandir($directory);
649
            $pathinfo = "error.error";
0 ignored issues
show
Unused Code introduced by
The assignment to $pathinfo is dead and can be removed.
Loading history...
650
            foreach ($files as $file) {
651
                if (strpos($file, $userId . '.') !== false) {
652
                    $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

652
                    $pathinfo = $userId . "." . /** @scrutinizer ignore-type */ pathinfo($file, PATHINFO_EXTENSION);
Loading history...
653
                }
654
            }
655
    
656
            // Delete the user's current background image if it exists
657
            while (findBackground($userId) !== "error.error") {
658
                $avatarName = "assets/img/background-img/" . findBackground(Auth::id());
659
                unlink(base_path($avatarName));
660
            }
661
                
662
            $fileName = $userId . '_' . time() . "." . $customBackground->extension();
663
            $customBackground->move(base_path('assets/img/background-img/'), $fileName);
664
    
665
            if (extension_loaded('imagick')) {
666
                $imagePath = base_path('assets/img/background-img/') . $fileName;
667
                $image = new \Imagick($imagePath);
668
                $image->stripImage();
669
                $image->writeImage($imagePath);
670
            }
671
    
672
            return redirect('/studio/theme');
673
        }
674
    
675
        return redirect('/studio/theme')->with('error', 'Please select a valid image file.');
676
    }
677
678
    //Delete custom background image
679
    public function removeBackground()
680
    {
681
        $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...
682
683
        // Delete the user's current background image if it exists
684
        while (findBackground($userId) !== "error.error") {
685
            $avatarName = "assets/img/background-img/" . findBackground(Auth::id());
686
            unlink(base_path($avatarName));
687
        }
688
689
        return back();
690
    }
691
692
693
    //Show custom theme
694
    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

694
    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...
695
    {
696
        $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...
697
698
        $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...
699
700
        return view('/studio/theme', $data);
701
    }
702
703
    //Save custom theme
704
    public function editTheme(request $request)
705
    {
706
        $request->validate([
707
            'zip' => 'sometimes|mimes:zip',
708
        ]);
709
710
        $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...
711
712
        $zipfile = $request->file('zip');
713
714
        $theme = $request->theme;
715
        $message = "";
716
717
        User::where('id', $userId)->update(['theme' => $theme]);
718
719
720
721
        if (!empty($zipfile)) {
722
723
            $zipfile->move(base_path('/themes'), "temp.zip");
724
725
            $zip = new ZipArchive;
726
            $zip->open(base_path() . '/themes/temp.zip');
727
            $zip->extractTo(base_path() . '/themes');
728
            $zip->close();
729
            unlink(base_path() . '/themes/temp.zip');
730
731
            // Removes version numbers from folder.
732
733
            $folder = base_path('themes');
734
            $regex = '/[0-9.-]/';
735
            $files = scandir($folder);
736
737
            foreach ($files as $file) {
738
                if ($file !== '.' && $file !== '..') {
739
                    if (preg_match($regex, $file)) {
740
                        $new_file = preg_replace($regex, '', $file);
741
                        File::copyDirectory($folder . '/' . $file, $folder . '/' . $new_file);
742
                        $dirname = $folder . '/' . $file;
743
                        if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
744
                            system('rmdir ' . escapeshellarg($dirname) . ' /s /q');
745
                        } else {
746
                            system("rm -rf " . escapeshellarg($dirname));
747
                        }
748
                    }
749
                }
750
            }
751
        }
752
753
754
        return Redirect('/studio/theme')->with("success", $message);
755
    }
756
757
    //Show user (name, email, password)
758
    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

758
    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...
759
    {
760
        $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...
761
762
        $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...
763
764
        return view('/studio/profile', $data);
765
    }
766
767
    //Save user (name, email, password)
768
    public function editProfile(request $request)
769
    {
770
        $request->validate([
771
            'name' => 'sometimes|required|unique:users',
772
            'email' => 'sometimes|required|email|unique:users',
773
            'password' => 'sometimes|min:8',
774
        ]);
775
776
        $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...
777
778
        $name = $request->name;
779
        $email = $request->email;
780
        $password = Hash::make($request->password);
781
782
        if ($request->name != '') {
783
            User::where('id', $userId)->update(['name' => $name]);
784
        } elseif ($request->email != '') {
785
            User::where('id', $userId)->update(['email' => $email]);
786
        } elseif ($request->password != '') {
787
            User::where('id', $userId)->update(['password' => $password]);
788
            Auth::logout();
789
        }
790
        return back();
791
    }
792
793
    //Show user theme credit page
794
    public function theme(request $request)
795
    {
796
        $littlelink_name = $request->littlelink;
797
        $id = User::select('id')->where('littlelink_name', $littlelink_name)->value('id');
798
799
        if (empty($id)) {
800
            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...
801
        }
802
803
        $userinfo = User::select('name', 'littlelink_name', 'littlelink_description', 'theme')->where('id', $id)->first();
804
        $information = User::select('name', 'littlelink_name', 'littlelink_description', 'theme')->where('id', $id)->get();
805
806
        $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();
807
808
        return view('components/theme', ['userinfo' => $userinfo, 'information' => $information, 'links' => $links, 'littlelink_name' => $littlelink_name]);
809
    }
810
811
    //Delete existing user
812
    public function deleteUser(request $request)
813
    {
814
815
        // echo $request->id;
816
        // echo "<br>";
817
        // echo Auth::id();
818
        $id = $request->id;
819
820
    if($id == Auth::id() and $id != "1") {
821
822
        Link::where('user_id', $id)->delete();
823
824
        $user = User::find($id);
825
826
        Schema::disableForeignKeyConstraints();
827
        $user->forceDelete();
828
        Schema::enableForeignKeyConstraints();
829
    }
830
831
        return redirect('/');
832
    }
833
834
    //Delete profile picture
835
    public function delProfilePicture()
836
    {
837
        $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...
838
839
        // Delete the user's current avatar if it exists
840
        while (findAvatar($userId) !== "error.error") {
841
            $avatarName = findAvatar($userId);
842
            unlink(base_path($avatarName));
843
        }
844
845
        return back();
846
    }
847
848
    //Export user links
849
    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

849
    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...
850
    {
851
        $userId = Auth::id();
852
        $user = User::find($userId);
853
        $links = Link::where('user_id', $userId)->get();
854
        
855
        if (!$user) {
856
            // handle the case where the user is null
857
            return response()->json(['message' => 'User not found'], 404);
858
        }
859
860
        $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...
861
862
        $domain = $_SERVER['HTTP_HOST'];
863
        $date = date('Y-m-d_H-i-s');
864
        $fileName = "links-$domain-$date.json";
865
        $headers = [
866
            'Content-Type' => 'application/json',
867
            'Content-Disposition' => 'attachment; filename="'.$fileName.'"',
868
        ];
869
        return response()->json($userData, 200, $headers);
870
871
        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...
872
    }
873
874
    //Export all user data
875
    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

875
    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...
876
    {
877
        $userId = Auth::id();
878
        $user = User::find($userId);
879
        $links = Link::where('user_id', $userId)->get();
880
    
881
        if (!$user) {
882
            // handle the case where the user is null
883
            return response()->json(['message' => 'User not found'], 404);
884
        }
885
    
886
        $userData = $user->toArray();
887
        $userData['links'] = $links->toArray();
888
889
        if (file_exists(base_path(findAvatar($userId)))){
890
            $imagePath = base_path(findAvatar($userId));
891
            $imageData = base64_encode(file_get_contents($imagePath));
892
            $userData['image_data'] = $imageData;
893
    
894
            $imageExtension = pathinfo($imagePath, PATHINFO_EXTENSION);
895
            $userData['image_extension'] = $imageExtension;
896
        }
897
    
898
        $domain = $_SERVER['HTTP_HOST'];
899
        $date = date('Y-m-d_H-i-s');
900
        $fileName = "user_data-$domain-$date.json";
901
        $headers = [
902
            'Content-Type' => 'application/json',
903
            'Content-Disposition' => 'attachment; filename="'.$fileName.'"',
904
        ];
905
        return response()->json($userData, 200, $headers);
906
    
907
        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...
908
    }    
909
910
    public function importData(Request $request)
911
    {
912
        try {
913
            // Get the JSON data from the uploaded file
914
            if (!$request->hasFile('import') || !$request->file('import')->isValid()) {
915
                throw new \Exception('File not uploaded or is faulty');
916
            }
917
            $file = $request->file('import');
918
            $jsonString = $file->get();
919
            $userData = json_decode($jsonString, true);
920
    
921
            // Update the authenticated user's profile data if defined in the JSON file
922
            $user = auth()->user();
923
            if (isset($userData['name'])) {
924
                $user->name = $userData['name'];
925
            }
926
927
            if (isset($userData['littlelink_description'])) {
928
                $sanitizedText = $userData['littlelink_description'];
929
                $sanitizedText = strip_tags($sanitizedText, '<a><p><strong><i><ul><ol><li><blockquote><h2><h3><h4>');
930
                $sanitizedText = preg_replace("/<a([^>]*)>/i", "<a $1 rel=\"noopener noreferrer nofollow\">", $sanitizedText);
931
                $sanitizedText = strip_tags_except_allowed_protocols($sanitizedText);
932
                $user->littlelink_description = $sanitizedText;
933
            }
934
935
            if (isset($userData['image_data'])) {
936
937
                $allowedExtensions = array('jpeg', 'jpg', 'png', 'webp');
938
                $userExtension = strtolower($userData['image_extension']);
939
940
                if (in_array($userExtension, $allowedExtensions)) {
941
                // Decode the image data from Base64
942
                $imageData = base64_decode($userData['image_data']);
943
944
                // Delete the user's current avatar if it exists
945
                while (findAvatar(Auth::id()) !== "error.error") {
946
                    $avatarName = findAvatar(Auth::id());
947
                    unlink(base_path($avatarName));
948
                }
949
                
950
                // Save the image to the correct path with the correct file name and extension
951
                $filename = $user->id . '.' . $userExtension;
952
                file_put_contents(base_path('assets/img/' . $filename), $imageData);
953
                
954
                // Update the user's image field with the correct file name
955
                $user->image = $filename;
956
                }
957
            }
958
959
            $user->save();
960
    
961
            // Delete all links for the authenticated user
962
            Link::where('user_id', $user->id)->delete();
963
    
964
            // Loop through each link in $userData and create a new link for the user
965
            foreach ($userData['links'] as $linkData) {
966
967
                $validatedData = Validator::make($linkData, [
968
                    'link' => 'nullable|exturl',
969
                ]);
970
971
                if ($validatedData->fails()) {
972
                    throw new \Exception('Invalid link');
973
                }
974
975
                $newLink = new Link();
976
    
977
                // Copy over the link data from $linkData to $newLink
978
                $newLink->button_id = $linkData['button_id'];
979
                $newLink->link = $linkData['link'];
980
                
981
                // Sanitize the title
982
                if ($linkData['button_id'] == 93) {
983
                    $sanitizedText = strip_tags($linkData['title'], '<a><p><strong><i><ul><ol><li><blockquote><h2><h3><h4>');
984
                    $sanitizedText = preg_replace("/<a([^>]*)>/i", "<a $1 rel=\"noopener noreferrer nofollow\">", $sanitizedText);
985
                    $sanitizedText = strip_tags_except_allowed_protocols($sanitizedText);
986
                
987
                    $newLink->title = $sanitizedText;
988
                } else {
989
                    $newLink->title = $linkData['title'];
990
                }
991
992
                $newLink->order = $linkData['order'];
993
                $newLink->click_number = 0;
994
                $newLink->up_link = $linkData['up_link'];
995
                $newLink->custom_css = $linkData['custom_css'];
996
                $newLink->custom_icon = $linkData['custom_icon'];
997
                $newLink->type = $linkData['type'];
998
                $newLink->type_params = $linkData['type_params'];
999
    
1000
                // Set the user ID to the current user's ID
1001
                $newLink->user_id = $user->id;
1002
    
1003
                // Save the new link to the database
1004
                $newLink->save();
1005
            }
1006
            return redirect('studio/profile')->with('success', __('messages.Profile updated successfully!'));
1007
        } catch (\Exception $e) {
1008
            return redirect('studio/profile')->with('error', __('messages.An error occurred while updating your profile.'));
1009
        }
1010
    }
1011
    
1012
1013
    // Hanle reports
1014
    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...
1015
    {
1016
        $formData = $request->all();
1017
    
1018
        try {
1019
            Mail::to(env('ADMIN_EMAIL'))->send(new ReportSubmissionMail($formData));
1020
            
1021
            return redirect('report')->with('success', __('messages.report_success'));
1022
        } catch (\Exception $e) {
1023
            return redirect()->back()->with('error', __('messages.report_error'));
1024
        }
1025
    }
1026
1027
    //Edit/save page icons
1028
    public function editIcons(Request $request)
1029
    {
1030
        $inputKeys = array_keys($request->except('_token'));
1031
1032
        $validationRules = [];
1033
1034
        foreach ($inputKeys as $platform) {
1035
            $validationRules[$platform] = 'nullable|exturl|max:255';
1036
        }
1037
1038
        $request->validate($validationRules);
1039
1040
        foreach ($inputKeys as $platform) {
1041
            $link = $request->input($platform);
1042
1043
            if (!empty($link)) {
1044
                $iconId = $this->searchIcon($platform);
1045
1046
                if (!is_null($iconId)) {
1047
                    $this->updateIcon($platform, $link);
1048
                } else {
1049
                    $this->addIcon($platform, $link);
1050
                }
1051
            }
1052
        }
1053
1054
        return redirect('studio/links#icons');
1055
    }
1056
1057
    private function searchIcon($icon)
1058
    {
1059
        return DB::table('links')
1060
            ->where('user_id', Auth::id())
1061
            ->where('title', $icon)
1062
            ->where('button_id', 94)
1063
            ->value('id');
1064
    }
1065
1066
    private function addIcon($icon, $link)
1067
    {
1068
        $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...
1069
        $links = new Link;
1070
        $links->link = $link;
1071
        $links->user_id = $userId;
1072
        $links->title = $icon;
1073
        $links->button_id = '94';
1074
        $links->save();
1075
        $links->order = ($links->id - 1);
1076
        $links->save();
1077
    }
1078
1079
    private function updateIcon($icon, $link)
1080
    {
1081
        Link::where('id', $this->searchIcon($icon))->update([
1082
            'button_id' => 94,
1083
            'link' => $link,
1084
            'title' => $icon
1085
        ]);
1086
    }
1087
}