Passed
Push — main ( 5a45e4...608abc )
by Julian
07:52 queued 03:48
created

UserController::addIcon()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 9
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 11
rs 9.9666
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
        $filteredLinkData['type_params'] = json_encode($customParams);
254
255
        if ($OrigLink) {
256
            $currentValues = $OrigLink->getAttributes();
257
            $nonNullFilteredLinkData = array_filter($filteredLinkData, function($value) {return !is_null($value);});
258
            $updatedValues = array_merge($currentValues, $nonNullFilteredLinkData);
259
            $OrigLink->update($updatedValues);
260
            $message = "Link updated";
261
        } else {
262
            $link = new Link($filteredLinkData);
263
            $link->user_id = $userId;
264
            $link->save();
265
            $message = "Link added";
266
        }
267
268
        // Step 8: Redirect
269
        $redirectUrl = $request->input('param') == 'add_more' ? 'studio/add-link' : 'studio/links';
270
        return Redirect($redirectUrl)->with('success', $message);
271
    }
272
    
273
    public function sortLinks(Request $request)
274
    {
275
        $linkOrders  = $request->input("linkOrders", []);
276
        $currentPage = $request->input("currentPage", 1);
277
        $perPage     = $request->input("perPage", 0);
278
279
        if ($perPage == 0) {
280
            $currentPage = 1;
281
        }
282
283
        $linkOrders = array_unique(array_filter($linkOrders));
284
        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...
285
            return response()->json([
286
                'status' => 'ERROR',
287
            ]);
288
        }
289
290
        $newOrder = $perPage * ($currentPage - 1);
291
        $linkNewOrders = [];
292
        foreach ($linkOrders as $linkId) {
293
            if ($linkId < 0) {
294
                continue;
295
            }
296
297
            $linkNewOrders[$linkId] = $newOrder;
298
            Link::where("id", $linkId)
299
                ->update([
300
                    'order' => $newOrder
301
                ]);
302
            $newOrder++;
303
        }
304
305
        return response()->json([
306
            'status' => 'OK',
307
            'linkOrders' => $linkNewOrders,
308
        ]);
309
    }
310
311
312
    //Count the number of clicks and redirect to link
313
    public function clickNumber(request $request)
314
    {
315
        $linkId = $request->id;
316
317
        if (substr($linkId, -1) == '+') {
318
            $linkWithoutPlus = str_replace('+', '', $linkId);
319
            return redirect(url('info/'.$linkWithoutPlus));
320
        }
321
    
322
        $link = Link::find($linkId);
323
324
        if (empty($link)) {
325
            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...
326
        }
327
328
        $link = $link->link;
329
330
        if (empty($linkId)) {
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::where('id', $linkId)->increment('click_number', 1);
335
336
        $response = redirect()->away($link);
337
        $response->header('X-Robots-Tag', 'noindex, nofollow');
338
339
        return $response;
340
    }
341
342
    //Download Vcard
343
    public function vcard(request $request)
344
    {
345
        $linkId = $request->id;
346
347
        // Find the link with the specified ID
348
        $link = Link::findOrFail($linkId);
349
350
        $json = $link->link;
351
352
        // Decode the JSON to a PHP array
353
        $data = json_decode($json, true);
354
        
355
        // Create a new vCard object
356
        $vcard = new VCard();
357
        
358
        // Set the vCard properties from the $data array
359
        $vcard->addName($data['last_name'], $data['first_name'], $data['middle_name'], $data['prefix'], $data['suffix']);
360
        $vcard->addCompany($data['organization']);
361
        $vcard->addJobtitle($data['vtitle']);
362
        $vcard->addRole($data['role']);
363
        $vcard->addEmail($data['email']);
364
        $vcard->addEmail($data['work_email'], 'WORK');
365
        $vcard->addURL($data['work_url'], 'WORK');
366
        $vcard->addPhoneNumber($data['home_phone'], 'HOME');
367
        $vcard->addPhoneNumber($data['work_phone'], 'WORK');
368
        $vcard->addPhoneNumber($data['cell_phone'], 'CELL');
369
        $vcard->addAddress($data['home_address_street'], '', $data['home_address_city'], $data['home_address_state'], $data['home_address_zip'], $data['home_address_country'], 'HOME');
370
        $vcard->addAddress($data['work_address_street'], '', $data['work_address_city'], $data['work_address_state'], $data['work_address_zip'], $data['work_address_country'], 'WORK');
371
        
372
373
        // $vcard->addPhoto(base_path('img/1.png'));
374
        
375
        // Generate the vCard file contents
376
        $file_contents = $vcard->getOutput();
377
        
378
        // Set the file headers for download
379
        $headers = [
380
            'Content-Type' => 'text/x-vcard',
381
            'Content-Disposition' => 'attachment; filename="contact.vcf"'
382
        ];
383
        
384
        Link::where('id', $linkId)->increment('click_number', 1);
385
386
        // Return the file download response
387
        return response()->make($file_contents, 200, $headers);
388
389
    }
390
391
    //Show link, click number, up link in links page
392
    public function showLinks()
393
    {
394
        $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...
395
        $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...
396
        
397
        $data['links'] = Link::select()->where('user_id', $userId)->orderBy('up_link', 'asc')->orderBy('order', 'asc')->paginate(99999);
398
        return view('studio/links', $data);
399
    }
400
401
    //Delete link
402
    public function deleteLink(request $request)
403
    {
404
        $linkId = $request->id;
405
406
        Link::where('id', $linkId)->delete();
407
408
        $directory = base_path("assets/favicon/icons");
409
        $files = scandir($directory);
410
        foreach($files as $file) {
411
        if (strpos($file, $linkId.".") !== false) {
412
        $pathinfo = pathinfo($file, PATHINFO_EXTENSION);}}
413
        if (isset($pathinfo)) {
414
        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...
415
        }
416
417
        return redirect('/studio/links');
418
    }
419
420
    //Delete icon
421
    public function clearIcon(request $request)
422
    {
423
        $linkId = $request->id;
424
425
        $directory = base_path("assets/favicon/icons");
426
        $files = scandir($directory);
427
        foreach($files as $file) {
428
        if (strpos($file, $linkId.".") !== false) {
429
        $pathinfo = pathinfo($file, PATHINFO_EXTENSION);}}
430
        if (isset($pathinfo)) {
431
        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...
432
        }
433
434
        return redirect('/studio/links');
435
    }
436
437
    //Raise link on the littlelink page
438
    public function upLink(request $request)
439
    {
440
        $linkId = $request->id;
441
        $upLink = $request->up;
442
443
        if ($upLink == 'yes') {
444
            $up = 'no';
445
        } elseif ($upLink == 'no') {
446
            $up = 'yes';
447
        }
448
449
        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...
450
451
        return back();
452
    }
453
454
    //Show link to edit
455
    public function showLink(request $request)
456
    {
457
        $linkId = $request->id;
458
459
        $link = Link::where('id', $linkId)->value('link');
460
        $title = Link::where('id', $linkId)->value('title');
461
        $order = Link::where('id', $linkId)->value('order');
462
        $custom_css = Link::where('id', $linkId)->value('custom_css');
463
        $buttonId = Link::where('id', $linkId)->value('button_id');
464
        $buttonName = Button::where('id', $buttonId)->value('name');
465
466
        $buttons = Button::select('id', 'name')->orderBy('name', 'asc')->get();
467
468
        return view('studio/edit-link', ['custom_css' => $custom_css, 'buttonId' => $buttonId, 'buttons' => $buttons, 'link' => $link, 'title' => $title, 'order' => $order, 'id' => $linkId, 'buttonName' => $buttonName]);
469
    }
470
471
    //Show custom CSS + custom icon
472
    public function showCSS(request $request)
473
    {
474
        $linkId = $request->id;
475
476
        $link = Link::where('id', $linkId)->value('link');
477
        $title = Link::where('id', $linkId)->value('title');
478
        $order = Link::where('id', $linkId)->value('order');
479
        $custom_css = Link::where('id', $linkId)->value('custom_css');
480
        $custom_icon = Link::where('id', $linkId)->value('custom_icon');
481
        $buttonId = Link::where('id', $linkId)->value('button_id');
482
483
        $buttons = Button::select('id', 'name')->get();
484
485
        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]);
486
    }
487
488
    //Save edit link
489
    public function editLink(request $request)
490
    {
491
        $request->validate([
492
            'link' => 'required|exturl',
493
            'title' => 'required',
494
            'button' => 'required',
495
        ]);
496
497
        if (stringStartsWith($request->link, 'http://') == 'true' or stringStartsWith($request->link, 'https://') == 'true' or stringStartsWith($request->link, 'mailto:') == 'true')
498
            $link1 = $request->link;
499
        else
500
            $link1 = 'https://' . $request->link;
501
        if (stringEndsWith($request->link, '/') == 'true')
502
            $link = rtrim($link1, "/ ");
503
        else
504
        $link = $link1;
505
        $title = $request->title;
506
        $order = $request->order;
507
        $button = $request->button;
508
        $linkId = $request->id;
509
510
        $buttonId = Button::select('id')->where('name', $button)->value('id');
511
512
        Link::where('id', $linkId)->update(['link' => $link, 'title' => $title, 'order' => $order, 'button_id' => $buttonId]);
513
514
        return redirect('/studio/links');
515
    }
516
517
    //Save edit custom CSS + custom icon
518
    public function editCSS(request $request)
519
    {
520
        $linkId = $request->id;
521
        $custom_icon = $request->custom_icon;
522
        $custom_css = $request->custom_css;
523
524
        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...
525
            Link::where('id', $linkId)->update(['custom_icon' => $custom_icon]);
526
        } 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...
527
            Link::where('id', $linkId)->update(['custom_css' => $custom_css]);
528
        } else {
529
            Link::where('id', $linkId)->update([]);
530
        }
531
        return Redirect('#result');
532
    }
533
534
    //Show littlelinke page for edit
535
    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

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

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

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

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

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

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