Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
100.00% |
1 / 1 |
|
100.00% |
10 / 10 |
CRAP | |
100.00% |
47 / 47 |
SearchMediaService | |
100.00% |
1 / 1 |
|
100.00% |
10 / 10 |
23 | |
100.00% |
47 / 47 |
getMediaFiles | |
100.00% |
1 / 1 |
1 | |
100.00% |
4 / 4 |
|||
searchFolder | |
100.00% |
1 / 1 |
4 | |
100.00% |
14 / 14 |
|||
addMediaFile | |
100.00% |
1 / 1 |
2 | |
100.00% |
3 / 3 |
|||
haveEnoughPictures | |
100.00% |
1 / 1 |
2 | |
100.00% |
3 / 3 |
|||
searchSubFolders | |
100.00% |
1 / 1 |
4 | |
100.00% |
7 / 7 |
|||
folderNeedsToBeSearched | |
100.00% |
1 / 1 |
3 | |
100.00% |
1 / 1 |
|||
abortSearch | |
100.00% |
1 / 1 |
2 | |
100.00% |
1 / 1 |
|||
isPreviewAvailable | |
100.00% |
1 / 1 |
3 | |
100.00% |
7 / 7 |
|||
addFolderToAlbumsArray | |
100.00% |
1 / 1 |
1 | |
100.00% |
3 / 3 |
|||
addFileToImagesArray | |
100.00% |
1 / 1 |
1 | |
100.00% |
4 / 4 |
<?php | |
/** | |
* Gallery | |
* | |
* This file is licensed under the Affero General Public License version 3 or | |
* later. See the COPYING file. | |
* | |
* @author Olivier Paroz <galleryapps@oparoz.com> | |
* | |
* @copyright Olivier Paroz 2014-2016 | |
*/ | |
namespace OCA\Gallery\Service; | |
use OCP\Files\Folder; | |
use OCP\Files\File; | |
/** | |
* Searches the instance for media files which can be shown | |
* | |
* @package OCA\Gallery\Service | |
*/ | |
class SearchMediaService extends FilesService { | |
/** @var null|array<string,string|int> */ | |
private $images = []; | |
/** @var null|array<string,string|int> */ | |
private $albums = []; | |
/** @var string[] */ | |
private $supportedMediaTypes; | |
/** | |
* This returns the list of all media files which can be shown starting from the given folder | |
* | |
* @param Folder $folderNode the current album | |
* @param string[] $supportedMediaTypes the list of supported media types | |
* @param array $features the list of supported features | |
* | |
* @return array<null|array<string,string|int>> all the images we could find | |
*/ | |
public function getMediaFiles($folderNode, $supportedMediaTypes, $features) { | |
$this->supportedMediaTypes = $supportedMediaTypes; | |
$this->features = $features; | |
$this->searchFolder($folderNode); | |
return [$this->images, $this->albums]; | |
} | |
/** | |
* Look for media files and folders in the given folder | |
* | |
* @param Folder $folder | |
* @param int $subDepth | |
* | |
* @return int | |
*/ | |
private function searchFolder($folder, $subDepth = 0) { | |
$albumImageCounter = 0; | |
$subFolders = []; | |
$this->addFolderToAlbumsArray($folder); | |
$nodes = $this->getNodes($folder, $subDepth); | |
foreach ($nodes as $node) { | |
if (!$this->isAllowedAndAvailable($node)) { | |
continue; | |
} | |
$nodeType = $this->getNodeType($node); | |
$subFolders = array_merge($subFolders, $this->getAllowedSubFolder($node, $nodeType)); | |
$albumImageCounter = $this->addMediaFile($node, $nodeType, $albumImageCounter); | |
if ($this->haveEnoughPictures($albumImageCounter, $subDepth)) { | |
break; | |
} | |
} | |
$albumImageCounter = $this->searchSubFolders($subFolders, $subDepth, $albumImageCounter); | |
return $albumImageCounter; | |
} | |
/** | |
* Adds the node to the list of images if it's a file and we can generate a preview of it | |
* | |
* @param File|Folder $node | |
* @param string $nodeType | |
* @param int $albumImageCounter | |
* | |
* @return int | |
*/ | |
private function addMediaFile($node, $nodeType, $albumImageCounter) { | |
if ($nodeType === 'file') { | |
$albumImageCounter = $albumImageCounter + (int)$this->isPreviewAvailable($node); | |
} | |
return $albumImageCounter; | |
} | |
/** | |
* Checks if we've collected enough pictures to be able to build the view | |
* | |
* An album is full when we find max 4 pictures at the same level | |
* | |
* @param int $albumImageCounter | |
* @param int $subDepth | |
* | |
* @return bool | |
*/ | |
private function haveEnoughPictures($albumImageCounter, $subDepth) { | |
if ($subDepth === 0) { | |
return false; | |
} | |
return $albumImageCounter === 4; | |
} | |
/** | |
* Looks for pictures in sub-folders | |
* | |
* If we're at level 0, we need to look for pictures in sub-folders no matter what | |
* If we're at deeper levels, we only need to go further if we haven't managed to find one | |
* picture in the current folder | |
* | |
* @param array <Folder> $subFolders | |
* @param int $subDepth | |
* @param int $albumImageCounter | |
* | |
* @return int | |
*/ | |
private function searchSubFolders($subFolders, $subDepth, $albumImageCounter) { | |
if ($this->folderNeedsToBeSearched($subFolders, $subDepth, $albumImageCounter)) { | |
$subDepth++; | |
foreach ($subFolders as $subFolder) { | |
//$this->logger->debug("Sub-Node path : {path}", ['path' => $subFolder->getPath()]); | |
$albumImageCounter = $this->searchFolder($subFolder, $subDepth); | |
if ($this->abortSearch($subDepth, $albumImageCounter)) { | |
break; | |
} | |
} | |
} | |
return $albumImageCounter; | |
} | |
/** | |
* Checks if we need to look for media files in the specified folder | |
* | |
* @param array <Folder> $subFolders | |
* @param int $subDepth | |
* @param int $albumImageCounter | |
* | |
* @return bool | |
*/ | |
private function folderNeedsToBeSearched($subFolders, $subDepth, $albumImageCounter) { | |
return !empty($subFolders) && ($subDepth === 0 || $albumImageCounter === 0); | |
} | |
/** | |
* Returns true if there is no need to check any other sub-folder at the same depth level | |
* | |
* @param int $subDepth | |
* @param int $count | |
* | |
* @return bool | |
*/ | |
private function abortSearch($subDepth, $count) { | |
return $subDepth > 1 && $count > 0; | |
} | |
/** | |
* Returns true if the file is of a supported media type and adds it to the array of items to | |
* return | |
* | |
* @todo We could potentially check if the file is readable ($file->stat() maybe) in order to | |
* only return valid files, but this may slow down operations | |
* | |
* @param File $file the file to test | |
* | |
* @return bool | |
*/ | |
private function isPreviewAvailable($file) { | |
try { | |
$mimeType = $file->getMimeType(); | |
if (in_array($mimeType, $this->supportedMediaTypes)) { | |
$this->addFileToImagesArray($mimeType, $file); | |
return true; | |
} | |
} catch (\Exception $exception) { | |
return false; | |
} | |
return false; | |
} | |
/** | |
* Adds a folder to the albums array | |
* | |
* @param Folder $folder the folder to add to the albums array | |
*/ | |
private function addFolderToAlbumsArray($folder) { | |
$albumData = $this->getFolderData($folder); | |
$this->albums[$albumData['path']] = $albumData; | |
} | |
/** | |
* Adds a file to the images array | |
* | |
* @param string $mimeType the media type of the file to add to the images array | |
* @param File $file the file to add to the images array | |
*/ | |
private function addFileToImagesArray($mimeType, $file) { | |
$imageData = $this->getNodeData($file); | |
$imageData['mimetype'] = $mimeType; | |
$this->images[] = $imageData; | |
} | |
} |