Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
* limitations under the License.
**/
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Response;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use OpenApi\Attributes as OA;
use Pion\Laravel\ChunkUpload\Exceptions\UploadMissingFileException;
use Pion\Laravel\ChunkUpload\Handler\AbstractHandler;
use Pion\Laravel\ChunkUpload\Receiver\FileReceiver;
Expand All @@ -33,6 +35,63 @@ class OAuth2ChunkedFilesApiController extends UploadController
* @throws UploadMissingFileException
*
*/
#[OA\Post(
path: "/api/public/v1/files/upload",
description: "Upload files using chunked upload mechanism. Supports large file uploads by splitting them into smaller chunks. The endpoint handles both complete uploads and chunked progress updates. Files are organized by MIME type and date in the storage system.",
summary: 'Upload file with chunked upload support',
operationId: 'uploadChunkedFile',
tags: ['Files'],
requestBody: new OA\RequestBody(
required: true,
content: new OA\MediaType(
mediaType: 'multipart/form-data',
schema: new OA\Schema(
required: ['file'],
properties: [
new OA\Property(
property: 'file',
type: 'string',
format: 'binary',
description: 'File to upload (can be a chunk of a larger file)'
),
new OA\Property(
property: 'resumableChunkNumber',
type: 'integer',
description: 'Current chunk number (for resumable.js library compatibility)',
example: 1
),
new OA\Property(
property: 'resumableTotalChunks',
type: 'integer',
description: 'Total number of chunks (for resumable.js library compatibility)',
example: 5
),
new OA\Property(
property: 'resumableIdentifier',
type: 'string',
description: 'Unique identifier for the file upload session (for resumable.js library compatibility)',
example: '12345-myfile-jpg'
),
]
)
)
),
responses: [
new OA\Response(
response: 200,
description: 'Success - Upload in progress (chunk uploaded successfully)',
content: new OA\JsonContent(ref: '#/components/schemas/ChunkedFileUploadProgressResponse')
),
new OA\Response(
response: 201,
description: 'Success - Upload complete (all chunks received and file saved)',
content: new OA\JsonContent(ref: '#/components/schemas/ChunkedFileUploadCompleteResponse')
),
new OA\Response(response: Response::HTTP_BAD_REQUEST, description: "Bad Request - Invalid file or missing required parameters"),
new OA\Response(response: Response::HTTP_UNPROCESSABLE_ENTITY, description: "Unprocessable Entity - Upload missing file exception"),
new OA\Response(response: Response::HTTP_INTERNAL_SERVER_ERROR, description: "Server Error - Upload failed or storage error")
]
)]
public function uploadFile(FileReceiver $receiver)
{
// check if the upload is success, throw exception or return response you need
Expand All @@ -57,4 +116,4 @@ public function uploadFile(FileReceiver $receiver)
]);
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -743,6 +743,7 @@ public function getAllByPage(PagingInfo $paging_info, Filter $filter = null, Ord
$start = time();
Log::debug(sprintf('DoctrineSummitAttendeeTicketRepository::getAllByPage'));
$total = $this->getFastCount($filter, $order);
if(!$total) return new PagingResponse(0, $paging_info->getPerPage(), $paging_info->getCurrentPage(), 0, []);
$ids = $this->getAllIdsByPage($paging_info, $filter, $order);
$query = $this->getEntityManager()->createQueryBuilder()
->select('e, a, o, tt, pc, b, bt, a_c, m')
Expand All @@ -762,6 +763,10 @@ public function getAllByPage(PagingInfo $paging_info, Filter $filter = null, Ord
$byId = [];
foreach ($rows as $e) $byId[$e->getId()] = $e;

$rows = $query->getQuery()->getResult();
$byId = [];
foreach ($rows as $e) $byId[$e->getId()] = $e;

$data = [];
foreach ($ids as $id) {
if (isset($byId[$id])) $data[] = $byId[$id];
Expand Down
124 changes: 90 additions & 34 deletions app/Repositories/Summit/DoctrineSummitEventRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,20 +98,12 @@ protected function getBaseEntity()
return SummitEvent::class;
}

/**
* @param PagingInfo $paging_info
* @param Filter|null $filter
* @param Order|null $order
* @return PagingResponse
*/
public function getAllByPage(PagingInfo $paging_info, Filter $filter = null, Order $order = null)
{

private function prepareRegularQuery($query, Filter $filter = null, Order $order = null){
$current_track_id = 0;
$current_member_id = 0;

if (!is_null($filter)) {
Log::debug(sprintf("DoctrineSummitEventRepository::getAllByPage filter %s", $filter));
// check for dependant filtering
$track_id_filter = $filter->getUniqueFilter('track_id');
if (!is_null($track_id_filter)) {
Expand All @@ -122,12 +114,7 @@ public function getAllByPage(PagingInfo $paging_info, Filter $filter = null, Ord
$current_member_id = intval($current_member_id_filter->getValue());
}
}

$query = $this->getEntityManager()->createQueryBuilder()
->select("e")
->distinct(true)
->from($this->getBaseEntity(), "e")
->leftJoin(Presentation::class, 'p', 'WITH', 'e.id = p.id');
$query = $query->leftJoin(Presentation::class, 'p', 'WITH', 'e.id = p.id');

if (is_null($order) || !$order->hasOrder("votes_count")) {
$query = $query
Expand Down Expand Up @@ -167,12 +154,19 @@ public function getAllByPage(PagingInfo $paging_info, Filter $filter = null, Ord
}
}

$shouldPerformRandomOrderingByPage = false;
if (!is_null($order)) {
if ($order->hasOrder("page_random")) {
$shouldPerformRandomOrderingByPage = true;
$order->removeOrder("page_random");
$can_view_private_events = self::isCurrentMemberOnGroup(IGroup::SummitAdministrators);

if (!$can_view_private_events) {
$idx = 1;
foreach (self::$forbidden_classes as $forbidden_class) {
$query = $query
->andWhere("not e INSTANCE OF :forbidden_class" . $idx);
$query->setParameter("forbidden_class" . $idx, $forbidden_class);
$idx++;
}
}

if (!is_null($order)) {
$order->apply2Query($query, $this->getOrderMappings());
if (!$order->hasOrder('id')) {
$query = $query->addOrderBy("e.id", 'ASC');
Expand All @@ -184,28 +178,90 @@ public function getAllByPage(PagingInfo $paging_info, Filter $filter = null, Ord
$query = $query->addOrderBy("e.id", 'ASC');
}

$can_view_private_events = self::isCurrentMemberOnGroup(IGroup::SummitAdministrators);
return $query;
}
/**
* @param Filter|null $filter
* @param Order|null $order
* @return int
*/
public function getFastCount(Filter $filter = null, Order $order = null){

if (!$can_view_private_events) {
$idx = 1;
foreach (self::$forbidden_classes as $forbidden_class) {
$query = $query
->andWhere("not e INSTANCE OF :forbidden_class" . $idx);
$query->setParameter("forbidden_class" . $idx, $forbidden_class);
$idx++;
}
}
$query = $this->getEntityManager()
->createQueryBuilder()
->select('COUNT(DISTINCT e.id)')
->from($this->getBaseEntity(), "e")
->distinct(false);

$query = $this->prepareRegularQuery($query, $filter, null);

return (int) $query->getQuery()->getSingleScalarResult();
}

/**
* @param PagingInfo $paging_info
* @param Filter|null $filter
* @param Order|null $order
* @return array
*/
public function getAllIdsByPage(PagingInfo $paging_info, Filter $filter = null, Order $order = null):array {

$query = $this->getEntityManager()
->createQueryBuilder()
->distinct(true)
->select("e.id")
->from($this->getBaseEntity(), "e");

$query = $this->prepareRegularQuery($query, $filter, $order);

$query = $query
->setFirstResult($paging_info->getOffset())
->setMaxResults($paging_info->getPerPage());

$paginator = new Paginator($query, $fetchJoinCollection = true);
$total = $paginator->count();
$res = $query->getQuery()->getArrayResult();
return array_column($res, 'id');
}
/**
* @param PagingInfo $paging_info
* @param Filter|null $filter
* @param Order|null $order
* @return PagingResponse
*/
public function getAllByPage(PagingInfo $paging_info, Filter $filter = null, Order $order = null)
{

$start = time();
$shouldPerformRandomOrderingByPage = false;
if (!is_null($order)) {
if ($order->hasOrder("page_random")) {
$shouldPerformRandomOrderingByPage = true;
$order->removeOrder("page_random");
}
}
Log::debug(sprintf('DoctrineSummitEventRepository::getAllByPage'));
$total = $this->getFastCount($filter, null);
if(!$total) return new PagingResponse(0, $paging_info->getPerPage(), $paging_info->getCurrentPage(), 0, []);
$ids = $this->getAllIdsByPage($paging_info, $filter, $order);

$query = $this->getEntityManager()->createQueryBuilder()
->select("e")
->from($this->getBaseEntity(), "e");

$query = $this->prepareRegularQuery($query, $filter, $order)
->andWhere('e.id IN (:ids)')
->setParameter('ids', $ids);

$rows = $query->getQuery()->getResult();
$byId = [];
foreach ($rows as $e) $byId[$e->getId()] = $e;

$data = [];
foreach ($ids as $id) {
if (isset($byId[$id])) $data[] = $byId[$id];
}

foreach ($paginator as $entity)
$data[] = $entity;
$end = time() - $start;
Log::debug(sprintf('DoctrineSummitEventRepository::getAllByPage %s seconds', $end));

if ($shouldPerformRandomOrderingByPage)
shuffle($data);
Expand Down