CoolCMS API

UploaderDropzone extends BaseComponent
in package

Admin copy of the front end {@see \App\UI\Front\Base\Components\UploaderDropzoneComponent\UploaderDropzone}.

Same logic (temp folder with a token, ajax upload/remove, file links via getUploadedFiles(), cleanup) and the same client side (the admin theme ships dropzone.js and _file_uploads.scss, activated by data-dropzone).

TODO: merge the front end and admin variants into a shared parent or trait so the logic is not implemented twice.

Table of Contents

Constants

CLIENT_RESIZE_MAX_DEFAULT  : int = 2560
Client-side image downscaling before upload: a longer side above this limit is rescaled to it on a canvas in `dropzone.js`. `0` disables it (attachments must not be altered).
CLIENT_RESIZE_QUALITY_DEFAULT  : float = 0.85
JPEG quality after client-side downscaling (PNG stays PNG and ignores it).

Properties

$container  : Container
$routerDispatcher  : RouterDispatcher
$translator  : ITranslator
$appContext  : AppContext
$componentParameters  : array<string, mixed>
$currencyContext  : CurrencyContext|null
$deviceDetector  : DeviceDetector|null
$languageContext  : LanguageContext|null
$localizationContext  : LocalizationContext|null
$settingContext  : SettingContext
$themeContext  : ThemeContext|null
$translatorDomain  : string|null
$allowedExtensions  : array<int, string>
Extensions without the dot (`['xml', 'csv', 'json']`), case-insensitive. Empty means only the MIME check applies. MIME sniffing of text formats (xml, csv, json) is unreliable (the browser or OS often sends `text/plain` or `application/octet-stream`), so a given list is authoritative and the MIME check is skipped for this upload instead of being added on top.
$allowedMimeTypes  : array<string|int, string>
$clientResizeMax  : int
Longer image side after client-side downscaling; `0` means no downscaling ({@see disableClientResize()}).
$clientResizeQuality  : float
$existingAssets  : array<string|int, mixed>
$fieldName  : string
$maxFiles  : int
$maxFileSize  : int
$session  : Session
$sessionSection  : SessionSection
$subDir  : string
$token  : string|null

Methods

__call()  : mixed
Dispatches `renderXyz()` to `render('Xyz', ...$args)`.
__construct()  : mixed
buildClientMimeFilter()  : string
Builds the MIME list for the client check in `dropzone.js` (`config.acceptedTypes.includes(file.type)`).
cleanup()  : void
Deletes the temp folder and removes the session record. Call after a successful save.
configure()  : self
createComponent()  : IComponent|null
disableClientResize()  : self
getAppContext()  : AppContext
getClientResizeMax()  : int
getClientResizeQuality()  : float
getComponentParameter()  : mixed
Returns a component parameter, or null when it is not set.
getContainer()  : Container
getCurrencyContext()  : CurrencyContext|null
getEffectiveMaxFileSize()  : int
Returns the application limit narrowed by the PHP limits (`upload_max_filesize`, `post_max_size`).
getLanguageContext()  : LanguageContext|null
getLocalizationContext()  : LocalizationContext|null
getPendingUploadNames()  : array<int, string>
Returns the names (only names) of files already uploaded to the temp folder for the current token.
getRouterDispatcher()  : RouterDispatcher
getSettingContext()  : SettingContext
getSettings()  : array<int, array<string, mixed>>
getTempDir()  : string|null
Returns the temp folder path from the session.
getThemeContext()  : ThemeContext|null
getToken()  : string|null
getUploadedFiles()  : array<int, array{name: string, path: string}>
Returns the uploaded files as links `[name, path]` without reading their content. Api reads each file itself when processing it ({@see \App\Core\Security\Upload\UploadedItem}), so the files never sit in memory together (base64 of all files at once would exceed `memory_limit`).
handleRemove()  : void
Ajax signal: deletes one file from the temp folder.
handleUpload()  : void
Ajax signal: uploads one file. The token comes from the URL (signal parameter) and says which session/folder the file belongs to.
hasServiceByType()  : bool
Returns whether the container has a service of the given type.
initializeAllContexts()  : void
injectDeviceDetector()  : void
onCreate()  : void
prepareTempDir()  : string
Prepares the temp folder for uploads. Returns the token that identifies the folder; the caller must pass it to the client (form hidden field and signal URL parameter), otherwise later requests miss the right folder.
render()  : void
setAppContext()  : $this
setClientResize()  : self
Client-side downscaling is set by the caller, who knows what the uploader carries. Attachments (PDFs, documents, complaint evidence photos) call {@see disableClientResize()} because their bytes must not change.
setComponentParameter()  : void
Sets a component parameter.
setCurrencyContext()  : $this
setExistingAssets()  : self
Sets the existing images (shown in the list).
setLanguageContext()  : $this
setLocalizationContext()  : $this
setSettingContext()  : $this
setThemeContext()  : $this
setToken()  : self
setup()  : void
setupAppContext()  : void
typedComponent()  : T
Returns a subcomponent with a verified type.
frontPresenter()  : BasePresenter|null
Returns the front presenter the component is attached to (null outside the front end or when detached).
getTranslator()  : ITranslator
setTemplateFile()  : void
setTranslator()  : self
createMultiplierComponent()  : Multiplier<string|int, IComponent>
Creates a multiplier for the component.
createNewComponentInstance()  : IComponent|null
Creates a new component instance without adding it to the presenter; used by the multiplier.
createStandardComponent()  : IComponent|null
Creates a standard component (not a multiplier).
getSessionKey()  : string
The session key contains the token, so forms open in parallel (several tabs) have their own record and do not overwrite each other's temp folder.
sendJsonResponse()  : void

Constants

CLIENT_RESIZE_MAX_DEFAULT

Client-side image downscaling before upload: a longer side above this limit is rescaled to it on a canvas in `dropzone.js`. `0` disables it (attachments must not be altered).

public int CLIENT_RESIZE_MAX_DEFAULT = 2560

Server-side checks (ImageUploadPolicy, Api) are unchanged; only transfer and temp size shrink.

CLIENT_RESIZE_QUALITY_DEFAULT

JPEG quality after client-side downscaling (PNG stays PNG and ignores it).

public float CLIENT_RESIZE_QUALITY_DEFAULT = 0.85

Properties

$componentParameters

protected array<string, mixed> $componentParameters = []

component parameters set by setComponentParameter()

$translatorDomain

protected string|null $translatorDomain = 'admin.base.components.uploaderDropzone'

$allowedExtensions

Extensions without the dot (`['xml', 'csv', 'json']`), case-insensitive. Empty means only the MIME check applies. MIME sniffing of text formats (xml, csv, json) is unreliable (the browser or OS often sends `text/plain` or `application/octet-stream`), so a given list is authoritative and the MIME check is skipped for this upload instead of being added on top.

private array<int, string> $allowedExtensions = []

$allowedMimeTypes

private array<string|int, string> $allowedMimeTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp', 'video/mp4', 'video/quicktime']

$clientResizeMax

Longer image side after client-side downscaling; `0` means no downscaling ({@see disableClientResize()}).

private int $clientResizeMax = self::CLIENT_RESIZE_MAX_DEFAULT

$clientResizeQuality

private float $clientResizeQuality = self::CLIENT_RESIZE_QUALITY_DEFAULT

Methods

__call()

Dispatches `renderXyz()` to `render('Xyz', ...$args)`.

public __call(string $name, array<string|int, mixed> $args) : mixed

Called only when the component has no renderXyz() method of its own.

Parameters
$name : string
$args : array<string|int, mixed>

__construct()

public __construct(Session $session) : mixed
Parameters
$session : Session

buildClientMimeFilter()

Builds the MIME list for the client check in `dropzone.js` (`config.acceptedTypes.includes(file.type)`).

public static buildClientMimeFilter(array<string|int, string> $allowedMimeTypes, array<string|int, string> $allowedExtensions) : string

Given extensions are authoritative (MIME sniffing of text formats is unreliable), so the result is an empty string: JS skips the type check and the server decides (handleUpload()).

Parameters
$allowedMimeTypes : array<string|int, string>
$allowedExtensions : array<string|int, string>
Return values
string

cleanup()

Deletes the temp folder and removes the session record. Call after a successful save.

public cleanup() : void

configure()

public configure(string $subDir[, int $maxFiles = 10 ][, array<string|int, string> $allowedMimeTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp', 'video/mp4', 'video/quicktime'] ][, int $maxFileSize = 50 * 1024 * 1024 ][, string $fieldName = 'uploaderItems' ][, array<int, string> $allowedExtensions = [] ]) : self
Parameters
$subDir : string
$maxFiles : int = 10
$allowedMimeTypes : array<string|int, string> = ['image/jpeg', 'image/png', 'image/gif', 'image/webp', 'video/mp4', 'video/quicktime']
$maxFileSize : int = 50 * 1024 * 1024
$fieldName : string = 'uploaderItems'
$allowedExtensions : array<int, string> = []

extensions without the dot, case-insensitive (see the property docblock)

Return values
self

createComponent()

public createComponent(string $name) : IComponent|null
Parameters
$name : string
Return values
IComponent|null

disableClientResize()

public disableClientResize() : self
Return values
self

getClientResizeMax()

public getClientResizeMax() : int
Return values
int

getClientResizeQuality()

public getClientResizeQuality() : float
Return values
float

getComponentParameter()

Returns a component parameter, or null when it is not set.

public getComponentParameter(string $name) : mixed
Parameters
$name : string

getContainer()

public getContainer() : Container
Return values
Container

getEffectiveMaxFileSize()

Returns the application limit narrowed by the PHP limits (`upload_max_filesize`, `post_max_size`).

public getEffectiveMaxFileSize() : int
Return values
int

getPendingUploadNames()

Returns the names (only names) of files already uploaded to the temp folder for the current token.

public getPendingUploadNames() : array<int, string>

On a form re-render (validation error etc.) it lets pending dropzone uploads render back into the gallery. Otherwise the re-render shows only existingAssets (DB), the client DOM item and its hidden uploaderItems would be lost, and the file would stay in temp but never reach its target. Returns an empty array when there is no token or folder (fresh GET).

Return values
array<int, string>

getSettings()

public getSettings() : array<int, array<string, mixed>>
Return values
array<int, array<string, mixed>>

getTempDir()

Returns the temp folder path from the session.

public getTempDir() : string|null
Return values
string|null

getUploadedFiles()

Returns the uploaded files as links `[name, path]` without reading their content. Api reads each file itself when processing it ({@see \App\Core\Security\Upload\UploadedItem}), so the files never sit in memory together (base64 of all files at once would exceed `memory_limit`).

public getUploadedFiles() : array<int, array{name: string, path: string}>

Call after a successful form submit. IMPORTANT: the folder must stay alive until the Api call finishes, so call cleanup() only after saving.

Return values
array<int, array{name: string, path: string}>

handleRemove()

Ajax signal: deletes one file from the temp folder.

public handleRemove(string $token) : void
Parameters
$token : string
Attributes
#[Requires]
$methods: 'POST'

handleUpload()

Ajax signal: uploads one file. The token comes from the URL (signal parameter) and says which session/folder the file belongs to.

public handleUpload(string $token) : void
Parameters
$token : string
Attributes
#[Requires]
$methods: 'POST'

hasServiceByType()

Returns whether the container has a service of the given type.

public hasServiceByType(string $className) : bool

The name is composed dynamically (module plus component), so class_exists() runs first, and a true result guarantees a valid type.

Parameters
$className : string
Tags
phpstan-assert-if-true

class-string $className

Return values
bool

prepareTempDir()

Prepares the temp folder for uploads. Returns the token that identifies the folder; the caller must pass it to the client (form hidden field and signal URL parameter), otherwise later requests miss the right folder.

public prepareTempDir([bool $forceNew = false ]) : string
Parameters
$forceNew : bool = false

deletes the old folder and creates a new one (fresh page load)

Return values
string

render()

public render([string $style = 'Style_1' ]) : void
Parameters
$style : string = 'Style_1'

setClientResize()

Client-side downscaling is set by the caller, who knows what the uploader carries. Attachments (PDFs, documents, complaint evidence photos) call {@see disableClientResize()} because their bytes must not change.

public setClientResize(int $maxSide[, float $quality = self::CLIENT_RESIZE_QUALITY_DEFAULT ]) : self
Parameters
$maxSide : int

longer side in px, 0 disables it

$quality : float = self::CLIENT_RESIZE_QUALITY_DEFAULT

JPEG quality 0-1

Return values
self

setComponentParameter()

Sets a component parameter.

public setComponentParameter(string $name, mixed $value) : void
Parameters
$name : string
$value : mixed

setExistingAssets()

Sets the existing images (shown in the list).

public setExistingAssets(array<string|int, mixed> $assets) : self
Parameters
$assets : array<string|int, mixed>

array with keys: imageId, thumbPath, isMain, order

Return values
self

setToken()

public setToken(string|null $token) : self
Parameters
$token : string|null
Return values
self

typedComponent()

Returns a subcomponent with a verified type.

public typedComponent(string $name, T> $type) : T

Use it instead of an inline @var above $this['x'] (which does not narrow the type) and instead of the generic IComponent that $this['x'] returns. See Form::typedComponent().

Parameters
$name : string
$type : T>
Tags
template
Return values
T

frontPresenter()

Returns the front presenter the component is attached to (null outside the front end or when detached).

protected frontPresenter() : BasePresenter|null
Return values
BasePresenter|null

getTranslator()

protected getTranslator() : ITranslator
Return values
ITranslator

setTemplateFile()

protected setTemplateFile(string $dir, string $filename) : void
Parameters
$dir : string
$filename : string

setTranslator()

protected setTranslator(ITranslator $translator) : self
Parameters
$translator : ITranslator
Return values
self

createMultiplierComponent()

Creates a multiplier for the component.

private createMultiplierComponent(string $name) : Multiplier<string|int, IComponent>
Parameters
$name : string
Return values
Multiplier<string|int, IComponent>

createNewComponentInstance()

Creates a new component instance without adding it to the presenter; used by the multiplier.

private createNewComponentInstance(string $baseName[, int|string|null $uniqueKey = null ]) : IComponent|null
Parameters
$baseName : string
$uniqueKey : int|string|null = null
Return values
IComponent|null

createStandardComponent()

Creates a standard component (not a multiplier).

private createStandardComponent(string $name) : IComponent|null
Parameters
$name : string
Return values
IComponent|null

getSessionKey()

The session key contains the token, so forms open in parallel (several tabs) have their own record and do not overwrite each other's temp folder.

private getSessionKey() : string
Return values
string

sendJsonResponse()

private sendJsonResponse(array<string|int, mixed> $data) : void
Parameters
$data : array<string|int, mixed>
On this page

Search results