/** * get all files and folders in a folder * @param string path * @param string root (optional) * @return array * * returns an array of assiciative arrays with the following keys: * - path * - name * - size * - mtime * - ctime * - mimetype * - encrypted * - versioned */ public static function getFolderContent($path, $root = false, $mimetype_filter = '') { if ($root === false) { $root = OC_Filesystem::getRoot(); } $parent = OC_FileCache::getId($path, $root); if ($parent == -1) { return array(); } $query = OC_DB::prepare('SELECT `id`,`path`,`name`,`ctime`,`mtime`,`mimetype`,`size`,`encrypted`,`versioned`,`writable` FROM `*PREFIX*fscache` WHERE `parent`=? AND (`mimetype` LIKE ? OR `mimetype` = ?)'); $result = $query->execute(array($parent, $mimetype_filter . '%', 'httpd/unix-directory'))->fetchAll(); if (is_array($result)) { return $result; } else { OC_Log::write('files', 'getFolderContent(): file not found in cache (' . $path . ')', OC_Log::DEBUG); return false; } }
/** * abstraction for running most basic operations * @param string $operation * @param string #path * @param array (optional) hooks * @param mixed (optional) $extraParam * @return mixed */ private function basicOperation($operation, $path, $hooks = array(), $extraParam = null) { $absolutePath = $this->getAbsolutePath($path); if (OC_FileProxy::runPreProxies($operation, $absolutePath, $extraParam) and OC_Filesystem::isValidPath($path)) { $path = $this->getRelativePath($absolutePath); if ($path == null) { return false; } $internalPath = $this->getInternalPath($path); $run = true; if (OC_Filesystem::$loaded and $this->fakeRoot == OC_Filesystem::getRoot()) { foreach ($hooks as $hook) { if ($hook != 'read') { OC_Hook::emit(OC_Filesystem::CLASSNAME, $hook, array(OC_Filesystem::signal_param_path => $path, OC_Filesystem::signal_param_run => &$run)); } else { OC_Hook::emit(OC_Filesystem::CLASSNAME, $hook, array(OC_Filesystem::signal_param_path => $path)); } } } if ($run and $storage = $this->getStorage($path)) { if (!is_null($extraParam)) { $result = $storage->{$operation}($internalPath, $extraParam); } else { $result = $storage->{$operation}($internalPath); } $result = OC_FileProxy::runPostProxies($operation, $this->getAbsolutePath($path), $result); if (OC_Filesystem::$loaded and $this->fakeRoot == OC_Filesystem::getRoot()) { if ($operation != 'fopen') { //no post hooks for fopen, the file stream is still open foreach ($hooks as $hook) { if ($hook != 'read') { OC_Hook::emit(OC_Filesystem::CLASSNAME, 'post_' . $hook, array(OC_Filesystem::signal_param_path => $path)); } } } } return $result; } } return null; }
/** * @brief Get shared items from the database * @param string Item type * @param string Item source or target (optional) * @param int SHARE_TYPE_USER, SHARE_TYPE_GROUP, SHARE_TYPE_LINK, $shareTypeUserAndGroups, or $shareTypeGroupUserUnique * @param string User or group the item is being shared with * @param string User that is the owner of shared items (optional) * @param int Format to convert items to with formatItems() * @param mixed Parameters to pass to formatItems() * @param int Number of items to return, -1 to return all matches (optional) * @param bool Include collection item types (optional) * @return mixed * * See public functions getItem(s)... for parameter usage * */ private static function getItems($itemType, $item = null, $shareType = null, $shareWith = null, $uidOwner = null, $format = self::FORMAT_NONE, $parameters = null, $limit = -1, $includeCollections = false, $itemShareWithBySource = false) { if (!self::isEnabled()) { if ($limit == 1 || isset($uidOwner) && isset($item)) { return false; } else { return array(); } } $backend = self::getBackend($itemType); // Get filesystem root to add it to the file target and remove from the file source, match file_source with the file cache if ($itemType == 'file' || $itemType == 'folder') { $root = \OC_Filesystem::getRoot(); $where = 'INNER JOIN `*PREFIX*fscache` ON `file_source` = `*PREFIX*fscache`.`id`'; if (!isset($item)) { $where .= ' WHERE `file_target` IS NOT NULL'; } $fileDependent = true; $queryArgs = array(); } else { $fileDependent = false; $root = ''; if ($includeCollections && !isset($item) && ($collectionTypes = self::getCollectionItemTypes($itemType))) { // If includeCollections is true, find collections of this item type, e.g. a music album contains songs if (!in_array($itemType, $collectionTypes)) { $itemTypes = array_merge(array($itemType), $collectionTypes); } else { $itemTypes = $collectionTypes; } $placeholders = join(',', array_fill(0, count($itemTypes), '?')); $where .= ' WHERE item_type IN (' . $placeholders . '))'; $queryArgs = $itemTypes; } else { $where = ' WHERE `item_type` = ?'; $queryArgs = array($itemType); } } if (isset($shareType)) { // Include all user and group items if ($shareType == self::$shareTypeUserAndGroups && isset($shareWith)) { $where .= ' AND `share_type` IN (?,?,?)'; $queryArgs[] = self::SHARE_TYPE_USER; $queryArgs[] = self::SHARE_TYPE_GROUP; $queryArgs[] = self::$shareTypeGroupUserUnique; $userAndGroups = array_merge(array($shareWith), \OC_Group::getUserGroups($shareWith)); $placeholders = join(',', array_fill(0, count($userAndGroups), '?')); $where .= ' AND `share_with` IN (' . $placeholders . ')'; $queryArgs = array_merge($queryArgs, $userAndGroups); // Don't include own group shares $where .= ' AND `uid_owner` != ?'; $queryArgs[] = $shareWith; } else { $where .= ' AND `share_type` = ?'; $queryArgs[] = $shareType; if (isset($shareWith)) { $where .= ' AND `share_with` = ?'; $queryArgs[] = $shareWith; } } } if (isset($uidOwner)) { $where .= ' AND `uid_owner` = ?'; $queryArgs[] = $uidOwner; if (!isset($shareType)) { // Prevent unique user targets for group shares from being selected $where .= ' AND `share_type` != ?'; $queryArgs[] = self::$shareTypeGroupUserUnique; } if ($itemType == 'file' || $itemType == 'folder') { $column = 'file_source'; } else { $column = 'item_source'; } } else { if ($itemType == 'file' || $itemType == 'folder') { $column = 'file_target'; } else { $column = 'item_target'; } } if (isset($item)) { if ($includeCollections && ($collectionTypes = self::getCollectionItemTypes($itemType))) { $where .= ' AND ('; } else { $where .= ' AND'; } // If looking for own shared items, check item_source else check item_target if (isset($uidOwner) || $itemShareWithBySource) { // If item type is a file, file source needs to be checked in case the item was converted if ($itemType == 'file' || $itemType == 'folder') { $where .= ' `file_source` = ?'; $column = 'file_source'; } else { $where .= ' `item_source` = ?'; $column = 'item_source'; } } else { if ($itemType == 'file' || $itemType == 'folder') { $where .= ' `file_target` = ?'; $item = \OC_Filesystem::normalizePath($item); } else { $where .= ' `item_target` = ?'; } } $queryArgs[] = $item; if ($includeCollections && $collectionTypes) { $placeholders = join(',', array_fill(0, count($collectionTypes), '?')); $where .= ' OR item_type IN (' . $placeholders . '))'; $queryArgs = array_merge($queryArgs, $collectionTypes); } } if ($limit != -1 && !$includeCollections) { if ($shareType == self::$shareTypeUserAndGroups) { // Make sure the unique user target is returned if it exists, unique targets should follow the group share in the database // If the limit is not 1, the filtering can be done later $where .= ' ORDER BY `*PREFIX*share`.`id` DESC'; } // The limit must be at least 3, because filtering needs to be done if ($limit < 3) { $queryLimit = 3; } else { $queryLimit = $limit; } } else { $queryLimit = null; } // TODO Optimize selects if ($format == self::FORMAT_STATUSES) { if ($itemType == 'file' || $itemType == 'folder') { $select = '`*PREFIX*share`.`id`, `item_type`, `*PREFIX*share`.`parent`, `share_type`, `file_source`, `path`, `expiration`'; } else { $select = '`id`, `item_type`, `item_source`, `parent`, `share_type`, `expiration`'; } } else { if (isset($uidOwner)) { if ($itemType == 'file' || $itemType == 'folder') { $select = '`*PREFIX*share`.`id`, `item_type`, `*PREFIX*share`.`parent`, `share_type`, `share_with`, `file_source`, `path`, `permissions`, `stime`, `expiration`'; } else { $select = '`id`, `item_type`, `item_source`, `parent`, `share_type`, `share_with`, `permissions`, `stime`, `file_source`, `expiration`'; } } else { if ($fileDependent) { if (($itemType == 'file' || $itemType == 'folder') && $format == \OC_Share_Backend_File::FORMAT_FILE_APP || $format == \OC_Share_Backend_File::FORMAT_FILE_APP_ROOT) { $select = '`*PREFIX*share`.`id`, `item_type`, `*PREFIX*share`.`parent`, `uid_owner`, `share_type`, `share_with`, `file_source`, `path`, `file_target`, `permissions`, `expiration`, `name`, `ctime`, `mtime`, `mimetype`, `size`, `encrypted`, `versioned`, `writable`'; } else { $select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `item_target`, `*PREFIX*share`.`parent`, `share_type`, `share_with`, `uid_owner`, `file_source`, `path`, `file_target`, `permissions`, `stime`, `expiration`'; } } else { $select = '*'; } } } $root = strlen($root); $query = \OC_DB::prepare('SELECT ' . $select . ' FROM `*PREFIX*share` ' . $where, $queryLimit); $result = $query->execute($queryArgs); $items = array(); $targets = array(); while ($row = $result->fetchRow()) { // Filter out duplicate group shares for users with unique targets if ($row['share_type'] == self::$shareTypeGroupUserUnique && isset($items[$row['parent']])) { $row['share_type'] = self::SHARE_TYPE_GROUP; $row['share_with'] = $items[$row['parent']]['share_with']; // Remove the parent group share unset($items[$row['parent']]); if ($row['permissions'] == 0) { continue; } } else { if (!isset($uidOwner)) { // Check if the same target already exists if (isset($targets[$row[$column]])) { // Check if the same owner shared with the user twice through a group and user share - this is allowed $id = $targets[$row[$column]]; if ($items[$id]['uid_owner'] == $row['uid_owner']) { // Switch to group share type to ensure resharing conditions aren't bypassed if ($items[$id]['share_type'] != self::SHARE_TYPE_GROUP) { $items[$id]['share_type'] = self::SHARE_TYPE_GROUP; $items[$id]['share_with'] = $row['share_with']; } // Switch ids if sharing permission is granted on only one share to ensure correct parent is used if resharing if (~(int) $items[$id]['permissions'] & self::PERMISSION_SHARE && (int) $row['permissions'] & self::PERMISSION_SHARE) { $items[$row['id']] = $items[$id]; unset($items[$id]); $id = $row['id']; } // Combine the permissions for the item $items[$id]['permissions'] |= (int) $row['permissions']; continue; } } else { $targets[$row[$column]] = $row['id']; } } } // Remove root from file source paths if retrieving own shared items if (isset($uidOwner) && isset($row['path'])) { if (isset($row['parent'])) { $row['path'] = '/Shared/' . basename($row['path']); } else { $row['path'] = substr($row['path'], $root); } } if (isset($row['expiration'])) { $time = new \DateTime(); if ($row['expiration'] < date('Y-m-d H:i', $time->format('U') - $time->getOffset())) { self::delete($row['id']); continue; } } $items[$row['id']] = $row; } if (!empty($items)) { $collectionItems = array(); foreach ($items as &$row) { // Return only the item instead of a 2-dimensional array if ($limit == 1 && $row['item_type'] == $itemType && $row[$column] == $item) { if ($format == self::FORMAT_NONE) { return $row; } else { break; } } // Check if this is a collection of the requested item type if ($includeCollections && $collectionTypes && in_array($row['item_type'], $collectionTypes)) { if (($collectionBackend = self::getBackend($row['item_type'])) && $collectionBackend instanceof Share_Backend_Collection) { // Collections can be inside collections, check if the item is a collection if (isset($item) && $row['item_type'] == $itemType && $row[$column] == $item) { $collectionItems[] = $row; } else { $collection = array(); $collection['item_type'] = $row['item_type']; if ($row['item_type'] == 'file' || $row['item_type'] == 'folder') { $collection['path'] = basename($row['path']); } $row['collection'] = $collection; // Fetch all of the children sources $children = $collectionBackend->getChildren($row[$column]); foreach ($children as $child) { $childItem = $row; $childItem['item_type'] = $itemType; if ($row['item_type'] != 'file' && $row['item_type'] != 'folder') { $childItem['item_source'] = $child['source']; $childItem['item_target'] = $child['target']; } if ($backend instanceof Share_Backend_File_Dependent) { if ($row['item_type'] == 'file' || $row['item_type'] == 'folder') { $childItem['file_source'] = $child['source']; } else { $childItem['file_source'] = \OC_FileCache::getId($child['file_path']); } $childItem['file_target'] = \OC_Filesystem::normalizePath($child['file_path']); } if (isset($item)) { if ($childItem[$column] == $item) { // Return only the item instead of a 2-dimensional array if ($limit == 1) { if ($format == self::FORMAT_NONE) { return $childItem; } else { // Unset the items array and break out of both loops $items = array(); $items[] = $childItem; break 2; } } else { $collectionItems[] = $childItem; } } } else { $collectionItems[] = $childItem; } } } } // Remove collection item unset($items[$row['id']]); } } if (!empty($collectionItems)) { $items = array_merge($items, $collectionItems); } if ($format == self::FORMAT_NONE) { return $items; } else { if ($format == self::FORMAT_STATUSES) { $statuses = array(); // Switch column to path for files and folders, used for determining statuses inside of folders if ($itemType == 'file' || $itemType == 'folder') { $column = 'path'; } foreach ($items as $item) { if ($item['share_type'] == self::SHARE_TYPE_LINK) { $statuses[$item[$column]] = true; } else { if (!isset($statuses[$item[$column]])) { $statuses[$item[$column]] = false; } } } return $statuses; } else { return $backend->formatItems($items, $format, $parameters); } } } else { if ($limit == 1 || isset($uidOwner) && isset($item)) { return false; } } return array(); }
/** * find files by mimetype * @param string $part1 * @param string $part2 (optional) * @param string root (optional) * @return array of file paths * * $part1 and $part2 together form the complete mimetype. * e.g. searchByMime('text','plain') * * seccond mimetype part can be ommited * e.g. searchByMime('audio') */ public static function searchByMime($part1, $part2 = null, $root = false) { if ($root === false) { $root = OC_Filesystem::getRoot(); } $rootLen = strlen($root); $root .= '%'; $user = OC_User::getUser(); if (!$part2) { $query = OC_DB::prepare('SELECT `path` FROM `*PREFIX*fscache` WHERE `mimepart`=? AND `user`=? AND `path` LIKE ?'); $result = $query->execute(array($part1, $user, $root)); } else { $query = OC_DB::prepare('SELECT `path` FROM `*PREFIX*fscache` WHERE `mimetype`=? AND `user`=? AND `path` LIKE ? '); $result = $query->execute(array($part1 . '/' . $part2, $user, $root)); } $names = array(); while ($row = $result->fetchRow()) { $names[] = substr($row['path'], $rootLen); } return $names; }
public static function findFiles($path) { $images = OC_FileCache::searchByMime('image', '', OC_Filesystem::getRoot() . $path); $new = array(); foreach ($images as $i) { if (strpos($i, '/', 1) === FALSE) { $new[] = $path . $i; } } return $new; }
/** * check if a file or folder is updated outside owncloud * @param string path * @param string root (optional) * @return bool */ public static function isUpdated($path, $root = '') { if (!$root) { $root = OC_Filesystem::getRoot(); $view = OC_Filesystem::getView(); } else { if ($root == '/') { $root = ''; } $view = new OC_FilesystemView($root); } if (!$view->file_exists($path)) { return false; } $mtime = $view->filemtime($path); $isDir = $view->is_dir($path); $fullPath = $root . $path; $query = OC_DB::prepare('SELECT mtime FROM *PREFIX*fscache WHERE path_hash=?'); $result = $query->execute(array(md5($fullPath))); if ($row = $result->fetchRow()) { $cachedMTime = $row['mtime']; return $mtime > $cachedMTime; } else { //file not in cache, so it has to be updated if ($path == '/' or $path == '') { //dont auto update the root folder, it will be scanned return false; } return true; } }
private function runHooks($hooks, $path, $post = false) { $prefix = $post ? 'post_' : ''; $run = true; if (OC_Filesystem::$loaded and $this->fakeRoot == OC_Filesystem::getRoot()) { foreach ($hooks as $hook) { if ($hook != 'read') { OC_Hook::emit(OC_Filesystem::CLASSNAME, $prefix . $hook, array(OC_Filesystem::signal_param_run => &$run, OC_Filesystem::signal_param_path => $path)); } elseif (!$post) { OC_Hook::emit(OC_Filesystem::CLASSNAME, $prefix . $hook, array(OC_Filesystem::signal_param_path => $path)); } } } return $run; }
function get_absolute_path($path) { return OC_Config::getValue("datadirectory") . OC_Filesystem::getRoot() . "/" . $path; }