Passed
Push — main ( bdbaee...80491e )
by Julian
16:21 queued 10:39
created

UserController::AddUpdateLink()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 14
c 1
b 0
f 0
nc 4
nop 1
dl 0
loc 24
rs 9.7998
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')->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();
107
108
        return view('linkstack.linkstack', ['userinfo' => $userinfo, 'information' => $information, 'links' => $links, 'littlelink_name' => $littlelink_name]);
109
    }
110
111
    //Show littlelink page as home page if set in config
112
    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

112
    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...
113
    {
114
        $littlelink_name = env('HOME_URL');
115
        $id = User::select('id')->where('littlelink_name', $littlelink_name)->value('id');
116
117
        if (empty($id)) {
118
            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...
119
        }
120
     
121
        $userinfo = User::select('id', 'name', 'littlelink_name', 'littlelink_description', 'theme', 'role', 'block')->where('id', $id)->first();
122
        $information = User::select('name', 'littlelink_name', 'littlelink_description', 'theme')->where('id', $id)->get();
123
        
124
        $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();
125
126
        return view('linkstack.linkstack', ['userinfo' => $userinfo, 'information' => $information, 'links' => $links, 'littlelink_name' => $littlelink_name]);
127
    }
128
129
    //Redirect to user page
130
    public function userRedirect(request $request)
131
    {
132
        $id = $request->id;
133
        $user = User::select('littlelink_name')->where('id', $id)->value('littlelink_name');
134
135
        if (empty($id)) {
136
            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...
137
        }
138
     
139
        if (empty($user)) {
140
            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...
141
        }
142
143
        return redirect(url('@'.$user));
144
    }
145
146
    //Show add/update form
147
    public function AddUpdateLink($id = 0)
148
    {
149
        $linkData = $id ? Link::find($id) : new Link(['typename' => 'link', 'id' => '0']);
150
    
151
        $data = [
152
            'LinkTypes' => LinkType::get(),
153
            'LinkData' => $linkData,
154
            'LinkID' => $id,
155
            'linkTypeID' => "1",
156
            'title' => "Predefined Site",
157
        ];
158
    
159
        if (Route::currentRouteName() != 'showButtons' && $link = DB::table('links')->where('id', $id)->first()) {
160
            $bidToLinkTypeId = [
161
                1 => "2", 2 => "2", 42 => "3", 43 => "4", 93 => "5", 6 => "6", 7 => "6", 44 => "7", 96 => "8",
162
            ];
163
    
164
            $data['linkTypeID'] = $bidToLinkTypeId[$link->button_id] ?? "1";
165
            $data['title'] = LinkType::where('id', $data['linkTypeID'])->value('title');
166
        }
167
    
168
        $data['SelectedLinkType'] = $data['LinkTypes']->firstWhere('typename', $linkData['typename']);
169
    
170
        return view('studio/edit-link', $data);
171
    }
172
173
    //Save add link
174
    public function saveLink(Request $request)
175
    {
176
        $request->validate([
177
            'link' => 'sometimes|exturl',
178
        ]);
179
    
180
        $linkType = LinkType::find($request->linktype_id);
181
        $LinkTitle = ($request->link_text ?? $request->link_title) ?? $request->title;
182
        $LinkURL = $request->link_url ?? $request->link;
183
        $OrigLink = Link::find($request->linkid);
184
    
185
        $customParams = [];
186
        foreach ($request->all() as $key => $param) {
187
            if (str_starts_with($key, "_") || in_array($key, ['linktype_id', 'linktype_title', 'link_text', 'link_url'])) continue;
188
            $customParams[$key] = $param;
189
        }
190
    
191
        $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...
192
        $button = Button::where('name', $request->button)->first();
193
        if ($button && empty($LinkTitle)) $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...
194
    
195
        if ($linkType->typename == 'video' && empty($LinkTitle)) {
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...
Bug introduced by
The property typename does not seem to exist on Illuminate\Database\Eloq...gHasThroughRelationship.
Loading history...
196
            $embed = OEmbed::get($LinkURL);
197
            if ($embed) $LinkTitle = $embed->data()['title'];
198
        }
199
    
200
        $message = (ucwords($button?->name) ?? ucwords($linkType->typename)) . " has been ";
0 ignored issues
show
Bug introduced by
The property name does not seem to exist on Illuminate\Database\Eloq...Relations\HasOneThrough.
Loading history...
Bug introduced by
The property name does not seem to exist on Illuminate\Database\Eloq...elations\HasManyThrough.
Loading history...
201
    
202
        $linkData = [
203
            'link' => $LinkURL,
204
            'title' => $LinkTitle,
205
            'user_id' => $userId,
206
            'button_id' => $button?->id
0 ignored issues
show
Bug introduced by
The property id does not seem to exist on Illuminate\Database\Eloq...elations\HasManyThrough.
Loading history...
Bug introduced by
The property id does not seem to exist on Illuminate\Database\Eloq...Relations\HasOneThrough.
Loading history...
207
        ];
208
    
209
        if ($linkType->typename == "link" && $customParams['GetSiteIcon'] == "1") {
210
            $linkData['button_id'] = "2";
211
        } elseif ($linkType->typename == "link") {
212
            $linkData['button_id'] = "1";
213
        } elseif ($linkType->typename == "spacer") {
214
            $linkData['title'] = $customParams['height'] ?? null;
215
            $linkData['button_id'] = "43";
216
        } elseif ($linkType->typename == "heading") {
217
            $linkData['button_id'] = "42";
218
        } elseif ($linkType->typename == "text") {
219
            $sanitizedText = $request->text;
220
            $sanitizedText = strip_tags($sanitizedText, '<a><p><strong><i><ul><ol><li><blockquote><h2><h3><h4>');
221
            $sanitizedText = preg_replace("/<a([^>]*)>/i", "<a $1 rel=\"noopener noreferrer nofollow\">", $sanitizedText);
222
            $sanitizedText = strip_tags_except_allowed_protocols($sanitizedText);
223
            $linkData['title'] = $sanitizedText;
224
            $linkData['button_id'] = "93";
225
        } elseif (in_array($linkType->typename, ["email", "telephone"])) {
226
            $linkData['button_id'] = $button?->id;
227
        } elseif ($linkType->typename == "vcard") {
228
            $data = $request->only([
229
                'prefix', 'first_name', 'middle_name', 'last_name', 'suffix', 'nickname',
230
                'organization', 'vtitle', 'role', 'work_url', 'email', 'work_email',
231
                'home_phone', 'work_phone', 'cell_phone', 'home_address_label', 'home_address_street',
232
                'home_address_city', 'home_address_state', 'home_address_zip', 'home_address_country',
233
                'work_address_label', 'work_address_street', 'work_address_city', 'work_address_state',
234
                'work_address_zip', 'work_address_country'
235
            ]);
236
            $linkData['link'] = json_encode($data);
237
            $linkData['button_id'] = 96;
238
        }
239
    
240
        if ($OrigLink) {
241
            $OrigLink->update($linkData);
242
            $message .= "updated";
243
        } else {
244
            $links = new Link($linkData);
245
            $links->user_id = $userId;
246
            $links->save();
247
            $links->order = ($links->id - 1);
248
            $links->save();
249
            $message .= "added";
250
        }
251
    
252
        $redirectUrl = $request->input('param') == 'add_more' ? 'studio/add-link' : 'studio/links';
253
        return Redirect($redirectUrl)->with('success', $message);
254
    }
255
    
256
    public function sortLinks(Request $request)
257
    {
258
        $linkOrders  = $request->input("linkOrders", []);
259
        $currentPage = $request->input("currentPage", 1);
260
        $perPage     = $request->input("perPage", 0);
261
262
        if ($perPage == 0) {
263
            $currentPage = 1;
264
        }
265
266
        $linkOrders = array_unique(array_filter($linkOrders));
267
        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...
268
            return response()->json([
269
                'status' => 'ERROR',
270
            ]);
271
        }
272
273
        $newOrder = $perPage * ($currentPage - 1);
274
        $linkNewOrders = [];
275
        foreach ($linkOrders as $linkId) {
276
            if ($linkId < 0) {
277
                continue;
278
            }
279
280
            $linkNewOrders[$linkId] = $newOrder;
281
            Link::where("id", $linkId)
282
                ->update([
283
                    'order' => $newOrder
284
                ]);
285
            $newOrder++;
286
        }
287
288
        return response()->json([
289
            'status' => 'OK',
290
            'linkOrders' => $linkNewOrders,
291
        ]);
292
    }
293
294
295
    //Count the number of clicks and redirect to link
296
    public function clickNumber(request $request)
297
    {
298
        $linkId = $request->id;
299
300
        if (substr($linkId, -1) == '+') {
301
            $linkWithoutPlus = str_replace('+', '', $linkId);
302
            return redirect(url('info/'.$linkWithoutPlus));
303
        }
304
    
305
        $link = Link::find($linkId);
306
307
        if (empty($link)) {
308
            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...
309
        }
310
311
        $link = $link->link;
312
313
        if (empty($linkId)) {
314
            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...
315
        }
316
317
        Link::where('id', $linkId)->increment('click_number', 1);
318
319
        $response = redirect()->away($link);
320
        $response->header('X-Robots-Tag', 'noindex, nofollow');
321
322
        return $response;
323
    }
324
325
    //Download Vcard
326
    public function vcard(request $request)
327
    {
328
        $linkId = $request->id;
329
330
        // Find the link with the specified ID
331
        $link = Link::findOrFail($linkId);
332
333
        $json = $link->link;
334
335
        // Decode the JSON to a PHP array
336
        $data = json_decode($json, true);
337
        
338
        // Create a new vCard object
339
        $vcard = new VCard();
340
        
341
        // Set the vCard properties from the $data array
342
        $vcard->addName($data['last_name'], $data['first_name'], $data['middle_name'], $data['prefix'], $data['suffix']);
343
        $vcard->addCompany($data['organization']);
344
        $vcard->addJobtitle($data['vtitle']);
345
        $vcard->addRole($data['role']);
346
        $vcard->addEmail($data['email']);
347
        $vcard->addEmail($data['work_email'], 'WORK');
348
        $vcard->addURL($data['work_url'], 'WORK');
349
        $vcard->addPhoneNumber($data['home_phone'], 'HOME');
350
        $vcard->addPhoneNumber($data['work_phone'], 'WORK');
351
        $vcard->addPhoneNumber($data['cell_phone'], 'CELL');
352
        $vcard->addAddress($data['home_address_street'], '', $data['home_address_city'], $data['home_address_state'], $data['home_address_zip'], $data['home_address_country'], 'HOME');
353
        $vcard->addAddress($data['work_address_street'], '', $data['work_address_city'], $data['work_address_state'], $data['work_address_zip'], $data['work_address_country'], 'WORK');
354
        
355
356
        // $vcard->addPhoto(base_path('img/1.png'));
357
        
358
        // Generate the vCard file contents
359
        $file_contents = $vcard->getOutput();
360
        
361
        // Set the file headers for download
362
        $headers = [
363
            'Content-Type' => 'text/x-vcard',
364
            'Content-Disposition' => 'attachment; filename="contact.vcf"'
365
        ];
366
        
367
        Link::where('id', $linkId)->increment('click_number', 1);
368
369
        // Return the file download response
370
        return response()->make($file_contents, 200, $headers);
371
372
    }
373
374
    //Show link, click number, up link in links page
375
    public function showLinks()
376
    {
377
        $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...
378
        $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...
379
        
380
        $data['links'] = Link::select('id', 'link', 'title', 'order', 'click_number', 'up_link', 'links.button_id')->where('user_id', $userId)->orderBy('up_link', 'asc')->orderBy('order', 'asc')->paginate(99999);
381
        return view('studio/links', $data);
382
    }
383
384
    //Delete link
385
    public function deleteLink(request $request)
386
    {
387
        $linkId = $request->id;
388
389
        Link::where('id', $linkId)->delete();
390
391
        $directory = base_path("assets/favicon/icons");
392
        $files = scandir($directory);
393
        foreach($files as $file) {
394
        if (strpos($file, $linkId.".") !== false) {
395
        $pathinfo = pathinfo($file, PATHINFO_EXTENSION);}}
396
        if (isset($pathinfo)) {
397
        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...
398
        }
399
400
        return redirect('/studio/links');
401
    }
402
403
    //Delete icon
404
    public function clearIcon(request $request)
405
    {
406
        $linkId = $request->id;
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...
415
        }
416
417
        return redirect('/studio/links');
418
    }
419
420
    //Raise link on the littlelink page
421
    public function upLink(request $request)
422
    {
423
        $linkId = $request->id;
424
        $upLink = $request->up;
425
426
        if ($upLink == 'yes') {
427
            $up = 'no';
428
        } elseif ($upLink == 'no') {
429
            $up = 'yes';
430
        }
431
432
        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...
433
434
        return back();
435
    }
436
437
    //Show link to edit
438
    public function showLink(request $request)
439
    {
440
        $linkId = $request->id;
441
442
        $link = Link::where('id', $linkId)->value('link');
443
        $title = Link::where('id', $linkId)->value('title');
444
        $order = Link::where('id', $linkId)->value('order');
445
        $custom_css = Link::where('id', $linkId)->value('custom_css');
446
        $buttonId = Link::where('id', $linkId)->value('button_id');
447
        $buttonName = Button::where('id', $buttonId)->value('name');
448
449
        $buttons = Button::select('id', 'name')->orderBy('name', 'asc')->get();
450
451
        return view('studio/edit-link', ['custom_css' => $custom_css, 'buttonId' => $buttonId, 'buttons' => $buttons, 'link' => $link, 'title' => $title, 'order' => $order, 'id' => $linkId, 'buttonName' => $buttonName]);
452
    }
453
454
    //Show custom CSS + custom icon
455
    public function showCSS(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
        $custom_icon = Link::where('id', $linkId)->value('custom_icon');
464
        $buttonId = Link::where('id', $linkId)->value('button_id');
465
466
        $buttons = Button::select('id', 'name')->get();
467
468
        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]);
469
    }
470
471
    //Save edit link
472
    public function editLink(request $request)
473
    {
474
        $request->validate([
475
            'link' => 'required|exturl',
476
            'title' => 'required',
477
            'button' => 'required',
478
        ]);
479
480
        if (stringStartsWith($request->link, 'http://') == 'true' or stringStartsWith($request->link, 'https://') == 'true' or stringStartsWith($request->link, 'mailto:') == 'true')
481
            $link1 = $request->link;
482
        else
483
            $link1 = 'https://' . $request->link;
484
        if (stringEndsWith($request->link, '/') == 'true')
485
            $link = rtrim($link1, "/ ");
486
        else
487
        $link = $link1;
488
        $title = $request->title;
489
        $order = $request->order;
490
        $button = $request->button;
491
        $linkId = $request->id;
492
493
        $buttonId = Button::select('id')->where('name', $button)->value('id');
494
495
        Link::where('id', $linkId)->update(['link' => $link, 'title' => $title, 'order' => $order, 'button_id' => $buttonId]);
496
497
        return redirect('/studio/links');
498
    }
499
500
    //Save edit custom CSS + custom icon
501
    public function editCSS(request $request)
502
    {
503
        $linkId = $request->id;
504
        $custom_icon = $request->custom_icon;
505
        $custom_css = $request->custom_css;
506
507
        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...
508
            Link::where('id', $linkId)->update(['custom_icon' => $custom_icon]);
509
        } 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...
510
            Link::where('id', $linkId)->update(['custom_css' => $custom_css]);
511
        } else {
512
            Link::where('id', $linkId)->update([]);
513
        }
514
        return Redirect('#result');
515
    }
516
517
    //Show littlelinke page for edit
518
    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

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

629
                    $pathinfo = $userId . "." . /** @scrutinizer ignore-type */ pathinfo($file, PATHINFO_EXTENSION);
Loading history...
630
                }
631
            }
632
    
633
            // Delete the user's current background image if it exists
634
            while (findBackground($userId) !== "error.error") {
635
                $avatarName = "assets/img/background-img/" . findBackground(Auth::id());
636
                unlink(base_path($avatarName));
637
            }
638
                
639
            $fileName = $userId . '_' . time() . "." . $customBackground->extension();
640
            $customBackground->move(base_path('assets/img/background-img/'), $fileName);
641
    
642
            if (extension_loaded('imagick')) {
643
                $imagePath = base_path('assets/img/background-img/') . $fileName;
644
                $image = new \Imagick($imagePath);
645
                $image->stripImage();
646
                $image->writeImage($imagePath);
647
            }
648
    
649
            return redirect('/studio/theme');
650
        }
651
    
652
        return redirect('/studio/theme')->with('error', 'Please select a valid image file.');
653
    }
654
655
    //Delete custom background image
656
    public function removeBackground()
657
    {
658
        $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...
659
660
        // Delete the user's current background image if it exists
661
        while (findBackground($userId) !== "error.error") {
662
            $avatarName = "assets/img/background-img/" . findBackground(Auth::id());
663
            unlink(base_path($avatarName));
664
        }
665
666
        return back();
667
    }
668
669
670
    //Show custom theme
671
    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

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

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

826
    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...
827
    {
828
        $userId = Auth::id();
829
        $user = User::find($userId);
830
        $links = Link::where('user_id', $userId)->get();
831
        
832
        if (!$user) {
833
            // handle the case where the user is null
834
            return response()->json(['message' => 'User not found'], 404);
835
        }
836
837
        $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...
838
839
        $domain = $_SERVER['HTTP_HOST'];
840
        $date = date('Y-m-d_H-i-s');
841
        $fileName = "links-$domain-$date.json";
842
        $headers = [
843
            'Content-Type' => 'application/json',
844
            'Content-Disposition' => 'attachment; filename="'.$fileName.'"',
845
        ];
846
        return response()->json($userData, 200, $headers);
847
848
        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...
849
    }
850
851
    //Export all user data
852
    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

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