Passed
Push — main ( 80491e...c1a475 )
by Julian
04:23
created

UserController::littlelink()   B

Complexity

Conditions 8
Paths 14

Size

Total Lines 44
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

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

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

636
                    $pathinfo = $userId . "." . /** @scrutinizer ignore-type */ pathinfo($file, PATHINFO_EXTENSION);
Loading history...
637
                }
638
            }
639
    
640
            // Delete the user's current background image if it exists
641
            while (findBackground($userId) !== "error.error") {
642
                $avatarName = "assets/img/background-img/" . findBackground(Auth::id());
643
                unlink(base_path($avatarName));
644
            }
645
                
646
            $fileName = $userId . '_' . time() . "." . $customBackground->extension();
647
            $customBackground->move(base_path('assets/img/background-img/'), $fileName);
648
    
649
            if (extension_loaded('imagick')) {
650
                $imagePath = base_path('assets/img/background-img/') . $fileName;
651
                $image = new \Imagick($imagePath);
652
                $image->stripImage();
653
                $image->writeImage($imagePath);
654
            }
655
    
656
            return redirect('/studio/theme');
657
        }
658
    
659
        return redirect('/studio/theme')->with('error', 'Please select a valid image file.');
660
    }
661
662
    //Delete custom background image
663
    public function removeBackground()
664
    {
665
        $userId = Auth::user()->id;
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
666
667
        // Delete the user's current background image if it exists
668
        while (findBackground($userId) !== "error.error") {
669
            $avatarName = "assets/img/background-img/" . findBackground(Auth::id());
670
            unlink(base_path($avatarName));
671
        }
672
673
        return back();
674
    }
675
676
677
    //Show custom theme
678
    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

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

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

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

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