Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2680416
ArcanistFileDataRef.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Advanced/Developer...
View Handle
View Hovercard
Size
7 KB
Referenced Files
None
Subscribers
None
ArcanistFileDataRef.php
View Options
<?php
/**
* Reference to a file or block of file data which can be uploaded using
* @{class:ArcanistFileUploader}.
*
* You can either upload a file on disk by using @{method:setPath}, or upload
* a block of data in memory by using @{method:setData}.
*
* For usage examples, see @{class:ArcanistFileUploader}.
*
* After uploading, successful uploads will have @{method:getPHID} populated.
* Failed uploads will have @{method:getErrors} populated with a description
* of reasons for failure.
*
* @task config Configuring File References
* @task results Handling Upload Results
* @task uploader Uploader API
*/
final
class
ArcanistFileDataRef
extends
Phobject
{
private
$name
;
private
$data
;
private
$path
;
private
$hash
;
private
$size
;
private
$errors
=
array
(
)
;
private
$phid
;
private
$fileHandle
;
private
$deleteAfterEpoch
;
private
$viewPolicy
;
/* -( Configuring File References )---------------------------------------- */
/**
* Set a human-readable display filename, like "file.jpg".
*
* This name does not correspond to a path on disk, and is purely for
* human consumption.
*
* @param string $name Filename.
* @return $this
* @task config
*/
public
function
setName
(
$name
)
{
$this
->
name
=
$name
;
return
$this
;
}
/**
* @task config
*/
public
function
getName
(
)
{
return
$this
->
name
;
}
/**
* Set the data to upload as a single raw blob.
*
* You can specify file data by calling this method with a single blob of
* data, or by calling @{method:setPath} and providing a path to a file on
* disk.
*
* @param bytes $data Blob of file data.
* @task config
*/
public
function
setData
(
$data
)
{
$this
->
data
=
$data
;
return
$this
;
}
/**
* @task config
*/
public
function
getData
(
)
{
return
$this
->
data
;
}
/**
* Set the data to upload by pointing to a file on disk.
*
* You can specify file data by calling this method with a path, or by
* providing a blob of raw data to @{method:setData}.
*
* The path itself only provides data. If you want to name the file, you
* should also call @{method:setName}.
*
* @param string $path Path on disk to a file containing data to upload.
* @return $this
* @task config
*/
public
function
setPath
(
$path
)
{
$this
->
path
=
$path
;
return
$this
;
}
/**
* @task config
*/
public
function
getPath
(
)
{
return
$this
->
path
;
}
/**
* @task config
*/
public
function
setViewPolicy
(
$view_policy
)
{
$this
->
viewPolicy
=
$view_policy
;
return
$this
;
}
/**
* @task config
*/
public
function
getViewPolicy
(
)
{
return
$this
->
viewPolicy
;
}
/**
* Configure a file to be temporary instead of permanent.
*
* By default, files are retained indefinitely until explicitly deleted. If
* you want to upload a temporary file instead, you can specify an epoch
* timestamp. The file will be deleted after this time.
*
* @param int $epoch Epoch timestamp to retain the file until.
* @return $this
* @task config
*/
public
function
setDeleteAfterEpoch
(
$epoch
)
{
$this
->
deleteAfterEpoch
=
$epoch
;
return
$this
;
}
/**
* @task config
*/
public
function
getDeleteAfterEpoch
(
)
{
return
$this
->
deleteAfterEpoch
;
}
/* -( Handling Upload Results )-------------------------------------------- */
/**
* @task results
*/
public
function
getErrors
(
)
{
return
$this
->
errors
;
}
/**
* @task results
*/
public
function
getPHID
(
)
{
return
$this
->
phid
;
}
/* -( Uploader API )------------------------------------------------------- */
/**
* @task uploader
*/
public
function
willUpload
(
)
{
$have_data
=
(
$this
->
data
!==
null
)
;
$have_path
=
(
$this
->
path
!==
null
)
;
if
(
!
$have_data
&&
!
$have_path
)
{
throw
new
Exception
(
pht
(
'Specify setData() or setPath() when building a file data '
.
'reference.'
)
)
;
}
if
(
$have_data
&&
$have_path
)
{
throw
new
Exception
(
pht
(
'Specify either setData() or setPath() when building a file data '
.
'reference, but not both.'
)
)
;
}
if
(
$have_path
)
{
$path
=
$this
->
path
;
if
(
!
Filesystem
::
pathExists
(
$path
)
)
{
throw
new
Exception
(
pht
(
'Unable to upload file: path "%s" does not exist.'
,
$path
)
)
;
}
try
{
Filesystem
::
assertIsFile
(
$path
)
;
}
catch
(
FilesystemException
$ex
)
{
throw
new
Exception
(
pht
(
'Unable to upload file: path "%s" is not a file.'
,
$path
)
)
;
}
try
{
Filesystem
::
assertReadable
(
$path
)
;
}
catch
(
FilesystemException
$ex
)
{
throw
new
Exception
(
pht
(
'Unable to upload file: path "%s" is not readable.'
,
$path
)
)
;
}
$size
=
@
filesize
(
$path
)
;
if
(
$size
===
false
)
{
throw
new
Exception
(
pht
(
'Unable to upload file: failed to determine filesize of '
.
'path "%s".'
,
$path
)
)
;
}
$this
->
hash
=
$this
->
newFileHash
(
$path
)
;
$this
->
size
=
$size
;
}
else
{
$data
=
$this
->
data
;
$this
->
hash
=
$this
->
newDataHash
(
$data
)
;
$this
->
size
=
strlen
(
$data
)
;
}
}
/**
* @task uploader
*/
public
function
didFail
(
$error
)
{
$this
->
errors
[
]
=
$error
;
return
$this
;
}
/**
* @task uploader
*/
public
function
setPHID
(
$phid
)
{
$this
->
phid
=
$phid
;
return
$this
;
}
/**
* @task uploader
*/
public
function
getByteSize
(
)
{
if
(
$this
->
size
===
null
)
{
throw
new
PhutilInvalidStateException
(
'willUpload'
)
;
}
return
$this
->
size
;
}
/**
* @task uploader
*/
public
function
getContentHash
(
)
{
if
(
$this
->
size
===
null
)
{
throw
new
PhutilInvalidStateException
(
'willUpload'
)
;
}
return
$this
->
hash
;
}
/**
* @task uploader
*/
public
function
didUpload
(
)
{
if
(
$this
->
fileHandle
)
{
@
fclose
(
$this
->
fileHandle
)
;
$this
->
fileHandle
=
null
;
}
}
/**
* @task uploader
*/
public
function
readBytes
(
$start
,
$end
)
{
if
(
$this
->
size
===
null
)
{
throw
new
PhutilInvalidStateException
(
'willUpload'
)
;
}
$len
=
(
$end
-
$start
)
;
if
(
$this
->
data
!==
null
)
{
return
substr
(
$this
->
data
,
$start
,
$len
)
;
}
$path
=
$this
->
path
;
if
(
$this
->
fileHandle
===
null
)
{
$f
=
@
fopen
(
$path
,
'rb'
)
;
if
(
!
$f
)
{
throw
new
Exception
(
pht
(
'Unable to upload file: failed to open path "%s" for reading.'
,
$path
)
)
;
}
$this
->
fileHandle
=
$f
;
}
$f
=
$this
->
fileHandle
;
$ok
=
@
fseek
(
$f
,
$start
)
;
if
(
$ok
!==
0
)
{
throw
new
Exception
(
pht
(
'Unable to upload file: failed to fseek() to offset %d in file '
.
'at path "%s".'
,
$start
,
$path
)
)
;
}
$data
=
@
fread
(
$f
,
$len
)
;
if
(
$data
===
false
)
{
throw
new
Exception
(
pht
(
'Unable to upload file: failed to read %d bytes after offset %d '
.
'from file at path "%s".'
,
$len
,
$start
,
$path
)
)
;
}
return
$data
;
}
private
function
newFileHash
(
$path
)
{
$hash
=
hash_file
(
'sha256'
,
$path
,
$raw_output
=
false
)
;
if
(
$hash
===
false
)
{
return
null
;
}
return
$hash
;
}
private
function
newDataHash
(
$data
)
{
$hash
=
hash
(
'sha256'
,
$data
,
$raw_output
=
false
)
;
if
(
$hash
===
false
)
{
return
null
;
}
return
$hash
;
}
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Thu, Dec 19, 17:02 (22 h, 3 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1014861
Default Alt Text
ArcanistFileDataRef.php (7 KB)
Attached To
Mode
rARC Arcanist
Attached
Detach File
Event Timeline
Log In to Comment