Skip to content

Commit

Permalink
New Feature
Browse files Browse the repository at this point in the history
closes #14
  • Loading branch information
usernane committed Apr 28, 2023
1 parent a5c71cf commit 3c01a56
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 25 deletions.
12 changes: 12 additions & 0 deletions tests/webfiori/framework/test/FileTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,18 @@ public function test07() {
$this->expectExceptionMessage("No data is set to write.");
$file->write(false, true);
}
/**
* @test
*/
public function test08() {
$file = new File('in-dir.txt');
$file->read(0, 1);
$this->assertEquals('T', $file->getRawData());
$this->assertEquals([84], $file->toBytesArray());
$this->assertEquals(['54'], $file->toHexArray());
$file->read();
$this->assertEquals("This is to test if read from same directory is working.\n", $file->getRawData());
}
/**
* @test
*/
Expand Down
1 change: 1 addition & 0 deletions tests/webfiori/framework/test/in-dir.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This is to test if read from same directory is working.
90 changes: 65 additions & 25 deletions webfiori/file/File.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ public function __construct(string $fNameOrAbsPath = '', string $fPath = '') {
$this->rawData = '';
self::initErrHandler();
if (!$this->setPath($fPath)) {
$info = $this->_extractPathAndName($fNameOrAbsPath);
$info = $this->extractPathAndName($fNameOrAbsPath);
$this->setDir($info['path']);
$this->setName($info['name']);
} else {
Expand All @@ -105,6 +105,37 @@ public function __construct(string $fNameOrAbsPath = '', string $fPath = '') {
}
$this->id = -1;
}
/**
* Returns an array that contains directories names of the calling script.
*
* This method is used to extract the pathes of files at which they called
* this method.
*
* @return array An array that contains directories names of the calling files.
*/
public static function getCallingFilesPaths() : array {
$debugTrace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 15);
$retVal = [];

foreach ($debugTrace as $traceEntry) {
if (isset($traceEntry['file'])) {
$file = $traceEntry['file'];
$split = explode(DIRECTORY_SEPARATOR, $file);
$withoutFile = array_diff($split, [$split[count($split) - 1]]);
$dir = implode(DIRECTORY_SEPARATOR, $withoutFile);

if (strlen($dir) != 0) {
$dir .= DIRECTORY_SEPARATOR;

if (!in_array($dir, $retVal)) {
$retVal[] = $dir;
}
}
}
}

return $retVal;
}
private static function initErrHandler() {
self::$errFunc = function (int $errno, string $errstr, string $errfile, int $errline) {
throw new FileException($errstr.' At class File line '.$errline, $errno);
Expand Down Expand Up @@ -183,7 +214,7 @@ public function create(bool $createDirIfNotExist = false) {

if (!$this->isExist()) {
self::isDirectory($this->getDir(), $createDirIfNotExist);
$resource = $this->_createResource('wb', $fPath);
$resource = $this->createResource('wb', $fPath);

if (!is_resource($resource)) {
throw new FileException('Unable to create a file at \''.$fPath.'\'.');
Expand Down Expand Up @@ -512,9 +543,9 @@ public static function isFileExist(string $path) : bool {
* </ul>
*/
public function read(int $from = -1, int $to = -1) {
$fPath = $this->_checkNameAndPath();
$fPath = $this->checkNameAndPath();

if (!$this->_readHelper($fPath,$from,$to)) {
if (!$this->readHelper($fPath,$from,$to)) {
throw new FileException('File not found: \''.$fPath.'\'.');
}
}
Expand Down Expand Up @@ -611,7 +642,7 @@ public function setName(string $name) {

if (strlen($trimmed) != 0) {
$this->fileName = $name;
$this->_extractMimeFromName();
$this->extractMimeFromName();
}
}

Expand Down Expand Up @@ -641,7 +672,7 @@ public function setRawData(string $raw, bool $decode = false, bool $strict = fal
$this->setRawDataDecoded($raw, $strict);
} else {
$this->rawData = $raw;
$this->_setSize(strlen($raw));
$this->setSize(strlen($raw));
}
}
}
Expand All @@ -668,7 +699,7 @@ public function setRawDataDecoded(string $raw, bool $strict = false) {
throw new FileException('Base 64 decoding failed due to characters outside base 64 alphabet.');
}
$this->rawData = $decoded;
$this->_setSize(strlen($this->rawData));
$this->setSize(strlen($this->rawData));
}
/**
* Returns a JSON string that represents the file.
Expand Down Expand Up @@ -715,7 +746,7 @@ public function view(bool $asAttachment = false) {
if (strlen($raw) == 0) {
$this->read();
}
$this->_viewFileHelper($asAttachment);
$this->viewFileHelper($asAttachment);
}
/**
* Write raw binary data into a file.
Expand All @@ -740,11 +771,11 @@ public function view(bool $asAttachment = false) {
* @since 1.1.1
*/
public function write(bool $append = true, bool $createIfNotExist = false) {
$pathV = $this->_checkNameAndPath();
$pathV = $this->checkNameAndPath();
if ($createIfNotExist) {
$this->create(true);
}
$this->_writeHelper($pathV, $append === true);
$this->writeHelper($pathV, $append === true);
}

/**
Expand All @@ -761,8 +792,8 @@ public function writeEncoded() {
$currentName = $this->getName();
$this->setName($currentName.'.bin');
$this->create(true);
$pathV = $this->_checkNameAndPath();
$this->_writeHelper($pathV, false, true);
$pathV = $this->checkNameAndPath();
$this->writeHelper($pathV, false, true);
$this->setName($currentName);
}

Expand All @@ -772,21 +803,30 @@ public function writeEncoded() {
*
* @throws FileException
*/
private function _checkNameAndPath(): string {
private function checkNameAndPath(): string {
clearstatcache();
$fName = $this->getName();

if (strlen($fName) != 0) {
$fPath = $this->getDir();

if (strlen($fPath) != 0) {
if (strlen($fPath) == 0) {
$possiblePaths = self::getCallingFilesPaths();
foreach ($possiblePaths as $fPath) {

if (self::isFileExist($fPath.DIRECTORY_SEPARATOR.$fName)) {
$this->setDir($fPath);
return $this->getAbsolutePath();
}
}
} else {
return $this->getAbsolutePath();
}
throw new FileException('Path cannot be empty string.');
}
throw new FileException('File name cannot be empty string.');
}
private function _createResource($mode, $path) {
private function createResource($mode, $path) {
set_error_handler(self::$errFunc);
$resource = fopen($path, $mode);
restore_error_handler();
Expand All @@ -797,15 +837,15 @@ private function _createResource($mode, $path) {

return false;
}
private function _extractMimeFromName() {
private function extractMimeFromName() {
$exp = explode('.', $this->getName());

if (count($exp) > 1) {
$ext = $exp[count($exp) - 1];
$this->setMIME(MIME::getType($ext));
}
}
private function _extractPathAndName($absPath): array {
private function extractPathAndName($absPath): array {
$DS = DIRECTORY_SEPARATOR;
$cleanPath = str_replace('\\', $DS, str_replace('/', $DS, trim($absPath)));
$pathArr = explode($DS, $cleanPath);
Expand All @@ -829,12 +869,12 @@ private function _extractPathAndName($absPath): array {
'path' => ''
];
}
private function _readHelper($fPath,$from,$to) {
private function readHelper($fPath,$from,$to) {
if ($this->isExist()) {
$fSize = filesize($fPath);
$this->_setSize($fSize);
$this->setSize($fSize);
$bytesToRead = $to - $from > 0 ? $to - $from : $this->getSize();
$resource = $this->_createResource('rb', $fPath);
$resource = $this->createResource('rb', $fPath);

if ($bytesToRead > $this->getSize() || $to > $this->getSize()) {
throw new FileException('Reached end of file while trying to read '.$bytesToRead.' byte(s).');
Expand All @@ -859,7 +899,7 @@ private function _readHelper($fPath,$from,$to) {
throw new FileException('File not found: \''.$fPath.'\'.');
}
}
private function _setSize($size) {
private function setSize($size) {
if ($size >= 0) {
$this->fileSize = $size;
}
Expand Down Expand Up @@ -887,7 +927,7 @@ public static function fixPath($fPath) {

return $start.$trimmedPath;
}
private function _viewFileHelper($asAttachment) {
private function viewFileHelper($asAttachment) {
$contentType = $this->getMIME();

if (class_exists('\webfiori\http\Response')) {
Expand All @@ -905,7 +945,7 @@ private function _viewFileHelper($asAttachment) {
* @return bool
* @throws FileException
*/
private function _writeHelper(string $fPath, bool $append, bool $encode = false) {
private function writeHelper(string $fPath, bool $append, bool $encode = false) {
if (strlen($this->getRawData()) == 0) {
throw new FileException("No data is set to write.");
}
Expand All @@ -914,9 +954,9 @@ private function _writeHelper(string $fPath, bool $append, bool $encode = false)
throw new FileException("File not found: '$fPath'.");
} else {
if ($append) {
$resource = $this->_createResource('ab', $fPath);
$resource = $this->createResource('ab', $fPath);
} else {
$resource = $this->_createResource('rb+', $fPath);
$resource = $this->createResource('rb+', $fPath);
}
}

Expand Down

0 comments on commit 3c01a56

Please sign in to comment.