Passed
Push — main ( e7d9fd...a1592b )
by Nobufumi
02:28
created

ListTrait::isImageUrl()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Jidaikobo\Kontiki\Controllers\FileControllerTraits;
4
5
use Jidaikobo\Kontiki\Utils\Pagination;
6
use Psr\Http\Message\ResponseInterface as Response;
7
use Psr\Http\Message\ServerRequestInterface as Request;
8
9
trait ListTrait
10
{
11
    /**
12
     * Handles the AJAX request to fetch the file list.
13
     *
14
     * This method retrieves a list of files from the model, applies security headers
15
     * to the response, and then renders a view to display the file list.
16
     *
17
     * @return Response
18
     */
19
    public function filelist(Request $request, Response $response): Response
20
    {
21
        // Initialize Pagination and set total items
22
        $page = $request->getQueryParams()['page'] ?? 1;
23
        $itemsPerPage = 10;
24
        $pagination = new Pagination($page, $itemsPerPage);
25
26
        $keyword = $request->getQueryParams()['s'] ?? '';
27
        $query = $this->model->getQuery();
28
        $query = $this->model->buildSearchConditions($query, $keyword);
29
        $totalItems = $query->count();
30
31
        $pagination->setTotalItems($totalItems);
32
        $paginationHtml = $pagination->render(env('BASEPATH', '') . "/filelist");
33
34
        $items = $query->limit($pagination->getLimit())
35
                  ->offset($pagination->getOffset())
36
                  ->orderBy('created_at', 'desc')
37
                  ->get()
38
                  ->map(fn($item) => (array) $item)
39
                  ->toArray();
40
41
        $items = $this->processItemsForList($request, $items);
42
43
        $content = $this->view->fetch(
44
            'forms/incFilelist.php',
45
            [
46
                'items' => $items,
47
                'pagination' => $paginationHtml
48
            ]
49
        );
50
51
        $response->getBody()->write($content);
52
        return $response->withHeader('Content-Type', 'text/html')->withStatus(200);
0 ignored issues
show
Bug introduced by
The method withStatus() does not exist on Psr\Http\Message\MessageInterface. It seems like you code against a sub-type of Psr\Http\Message\MessageInterface such as Psr\Http\Message\ResponseInterface or Slim\Psr7\Response. ( Ignorable by Annotation )

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

52
        return $response->withHeader('Content-Type', 'text/html')->/** @scrutinizer ignore-call */ withStatus(200);
Loading history...
53
    }
54
55
    private function processItemsForList(Request $request, array $items): array
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

55
    private function processItemsForList(/** @scrutinizer ignore-unused */ Request $request, array $items): array

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...
56
    {
57
        foreach ($items as $key => $value) {
58
            $url = $this->pathToUrl($items[$key]['path']);
59
            $items[$key]['imageOrLink'] = $this->renderImageOrLink($url, $items[$key]['description'] ?? '');
60
            $items[$key]['url'] = $url;
61
            $items[$key]['description'] = $items[$key]['description'] ?? ''; // don't use null
62
            $items[$key]['isImage'] = $this->isImageUrl($url);
63
        }
64
        return $items;
65
    }
66
67
    /**
68
     * Determine whether a given URL points to an image file based on its extension.
69
     *
70
     * @param string $url The URL to check.
71
     * @return bool True if it's an image, false otherwise.
72
     */
73
    private function isImageUrl(string $url): bool
74
    {
75
        $imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp'];
76
        $pathInfo = pathinfo(parse_url($url, PHP_URL_PATH));
77
78
        return isset($pathInfo['extension']) &&
79
            in_array(strtolower($pathInfo['extension']), $imageExtensions, true);
80
    }
81
82
    /**
83
     * Render an image or a link based on the provided URL.
84
     *
85
     * @param string $url The input URL, either an image URL or a standard URL.
86
     * @param string|null $desc description text.
87
     * @return string The generated HTML.
88
     */
89
    private function renderImageOrLink(string $url, ?string $desc): string
90
    {
91
        if ($this->isImageUrl($url)) {
92
            $descText = e($desc);
93
            $imgSrc = e($url);
94
            return '<img src="' . $imgSrc . '" alt="' . __('enlarge_x', 'Enlarge :name', ['name' => $descText]) . '" class="clickable-image img-thumbnail" tabindex="0">';
95
        }
96
97
        // Otherwise, return an <a> tag for links
98
        $linkHref = e($url);
99
        $pathInfo = pathinfo(parse_url($url, PHP_URL_PATH));
100
        $extension = isset($pathInfo['extension']) ? strtolower($pathInfo['extension']) : null;
101
102
        switch ($extension) {
103
            case 'pdf':
104
                $class = 'fa-file-pdf';
105
                break;
106
            case 'zip':
107
                $class = 'fa-file-zip';
108
                break;
109
            default:
110
                $class = 'fa-file-text';
111
                break;
112
        }
113
114
        return '<a href="' . $linkHref . '" target="_blank" aria-label="' . __('downlaod') . '" download class="fa-solid ' . $class . ' display-3 mb-2"><span class="visually-hidden">' . __('downlaod_x', 'Download :name', ['name' => $desc]) . '</span></a>';
115
    }
116
117
    protected function pathToUrl(string $filePath): string
118
    {
119
        $filePath = realpath($filePath);
120
        $uploadDir = realpath(env('PROJECT_PATH', '') . env('UPLOADDIR'));
121
        $uploadBaseUrl = rtrim(env('BASEURL'), '/') . rtrim(env('BASEURL_UPLOAD_DIR'), '/');
122
123
        if (strpos($filePath, $uploadDir) === 0) {
124
            $relativePath = ltrim(str_replace($uploadDir, '', $filePath), '/');
125
            return $uploadBaseUrl . '/' . $relativePath;
126
        }
127
        throw new \InvalidArgumentException('The file path is not inside the upload directory.');
128
    }
129
}
130