Ejemplo n.º 1
0
 /**
  * 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;
     }
 }
Ejemplo n.º 2
0
 /**
  * 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;
 }
Ejemplo n.º 3
0
 /**
  * @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();
 }
Ejemplo n.º 4
0
 /**
  * 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;
 }
Ejemplo n.º 5
0
 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;
 }
Ejemplo n.º 6
0
 /**
  * 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;
     }
 }
Ejemplo n.º 7
0
 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;
 }
Ejemplo n.º 8
0
function get_absolute_path($path)
{
    return OC_Config::getValue("datadirectory") . OC_Filesystem::getRoot() . "/" . $path;
}