public static function get($path, $root = false) { if ($root === false) { $root = OC_Filesystem::getRoot(); } $path = $root . $path; $stmt = OC_DB::prepare('SELECT `id`, `path`,`ctime`,`mtime`,`mimetype`,`size`,`encrypted`,`versioned`,`writable` FROM `*PREFIX*fscache` WHERE `path_hash`=?'); if (!OC_DB::isError($stmt)) { $result = $stmt->execute(array(md5($path))); if (!OC_DB::isError($result)) { $result = $result->fetchRow(); } else { OC: Log::write('OC_FileCache_Cached', 'could not execute get: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR); $result = false; } } else { OC_Log::write('OC_FileCache_Cached', 'could not prepare get: ' . OC_DB::getErrorMessage($stmt), OC_Log::ERROR); $result = false; } if (is_array($result)) { if (isset(self::$savedData[$path])) { $result = array_merge($result, self::$savedData[$path]); } return $result; } else { if (isset(self::$savedData[$path])) { return self::$savedData[$path]; } else { return array(); } } }
public static function scan($id, $path, $storage) { $file = $storage->getLocalFile($path); $result = OC_Files_Antivirus::clamav_scan($file); switch ($result) { case CLAMAV_SCANRESULT_UNCHECKED: \OCP\Util::writeLog('files_antivirus', 'File "' . $path . '" from user "' . $user . '": is not checked', \OCP\Util::ERROR); break; case CLAMAV_SCANRESULT_INFECTED: $infected_action = \OCP\Config::getAppValue('files_antivirus', 'infected_action', 'only_log'); if ($infected_action == 'delete') { \OCP\Util::writeLog('files_antivirus', 'File "' . $path . '" from user "' . $user . '": is infected, file deleted', \OCP\Util::ERROR); unlink($file); } else { \OCP\Util::writeLog('files_antivirus', 'File "' . $path . '" from user "' . $user . '": is infected', \OCP\Util::ERROR); } break; case CLAMAV_SCANRESULT_CLEAN: $stmt = OCP\DB::prepare('INSERT INTO `*PREFIX*files_antivirus` (`fileid`, `check_time`) VALUES (?, ?)'); try { $result = $stmt->execute(array($id, time())); if (\OC_DB::isError($result)) { \OC_Log::write('files_antivirus', __METHOD__ . ', DB error: ' . \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); return; } } catch (\Exception $e) { \OCP\Util::writeLog('files_antivirus', __METHOD__ . ', exception: ' . $e->getMessage(), \OCP\Util::ERROR); } break; } }
/** * Get all items for the users we want to send an email to * * @param array $affectedUsers * @param int $maxTime * @return array Notification data (user => array of rows from the table) */ public function getItemsForUsers($affectedUsers, $maxTime) { $placeholders = implode(',', array_fill(0, sizeof($affectedUsers), '?')); $queryParams = $affectedUsers; array_unshift($queryParams, (int) $maxTime); $query = \OCP\DB::prepare('SELECT * ' . ' FROM `*PREFIX*activity_mq` ' . ' WHERE `amq_timestamp` <= ? ' . ' AND `amq_affecteduser` IN (' . $placeholders . ')' . ' ORDER BY `amq_timestamp` ASC'); $result = $query->execute($queryParams); $userActivityMap = array(); if (\OCP\DB::isError($result)) { \OCP\Util::writeLog('Activity', \OC_DB::getErrorMessage($result), \OC_Log::ERROR); } else { while ($row = $result->fetchRow()) { $userActivityMap[$row['amq_affecteduser']][] = $row; } } return $userActivityMap; }
public static function scan($id, $path, $storage) { $fileStatus = \OCA\Files_Antivirus\Scanner::scanFile($storage, $path); $result = $fileStatus->getNumericStatus(); //TODO: Fix undefined $user here switch ($result) { case \OCA\Files_Antivirus\Status::SCANRESULT_UNCHECKED: \OCP\Util::writeLog('files_antivirus', 'File "' . $path . '" with id "' . $id . '": is not checked', \OCP\Util::ERROR); break; case \OCA\Files_Antivirus\Status::SCANRESULT_INFECTED: $infected_action = \OCP\Config::getAppValue('files_antivirus', 'infected_action', 'only_log'); if ($infected_action == 'delete') { \OCP\Util::writeLog('files_antivirus', 'File "' . $path . '" with id "' . $id . '": is infected, file deleted', \OCP\Util::ERROR); $storage->unlink($path); } else { \OCP\Util::writeLog('files_antivirus', 'File "' . $path . '" with id "' . $id . '": is infected', \OCP\Util::ERROR); } break; case \OCA\Files_Antivirus\Status::SCANRESULT_CLEAN: try { $stmt = \OCP\DB::prepare('DELETE FROM `*PREFIX*files_antivirus` WHERE `fileid` = ?'); $result = $stmt->execute(array($id)); if (\OCP\DB::isError($result)) { \OCP\Util::writeLog('files_antivirus', __METHOD__ . ', DB error: ' . \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); return; } $stmt = \OCP\DB::prepare('INSERT INTO `*PREFIX*files_antivirus` (`fileid`, `check_time`) VALUES (?, ?)'); $result = $stmt->execute(array($id, time())); if (\OCP\DB::isError($result)) { \OCP\Util::writeLog('files_antivirus', __METHOD__ . ', DB error: ' . \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); return; } } catch (\Exception $e) { \OCP\Util::writeLog('files_antivirus', __METHOD__ . ', exception: ' . $e->getMessage(), \OCP\Util::ERROR); } break; } }
public function parseResponse($rawResponse, $result = null) { $matches = array(); if (is_null($result)) { // Daemon or socket mode // Load rules $query = \OCP\DB::prepare('SELECT * FROM `*PREFIX*files_antivirus_status` WHERE `status_type`=? and `status`=?'); try { $infectedResult = $query->execute(array(self::STATUS_TYPE_MATCH, self::SCANRESULT_INFECTED)); if (\OCP\DB::isError($infectedResult)) { \OCP\Util::writeLog('files_antivirus', __METHOD__ . 'DB error: ' . \OC_DB::getErrorMessage($infectedResult), \OCP\Util::ERROR); return; } $infectedRules = $infectedResult->fetchAll(); $uncheckedResult = $query->execute(array(self::STATUS_TYPE_MATCH, self::SCANRESULT_UNCHECKED)); if (\OCP\DB::isError($uncheckedResult)) { \OCP\Util::writeLog('files_antivirus', __METHOD__ . 'DB error: ' . \OC_DB::getErrorMessage($uncheckedResult), \OCP\Util::ERROR); return; } $uncheckedRules = $uncheckedResult->fetchAll(); $cleanResult = $query->execute(array(self::STATUS_TYPE_MATCH, self::SCANRESULT_CLEAN)); if (\OCP\DB::isError($cleanResult)) { \OCP\Util::writeLog('files_antivirus', __METHOD__ . 'DB error: ' . \OC_DB::getErrorMessage($cleanResult), \OCP\Util::ERROR); return; } $cleanRules = $cleanResult->fetchAll(); } catch (\Exception $e) { \OCP\Util::writeLog('files_antivirus', __METHOD__ . ', exception: ' . $e->getMessage(), \OCP\Util::ERROR); return; } $infectedRules = $infectedRules ? $infectedRules : array(); $uncheckedRules = $uncheckedRules ? $uncheckedRules : array(); $cleanRules = $cleanRules ? $cleanRules : array(); $isMatched = false; // order: clean, infected, try to guess error $allRules = array_merge($cleanRules, $infectedRules, $uncheckedRules); foreach ($allRules as $rule) { if (preg_match($rule['match'], $rawResponse, $matches)) { $isMatched = true; $this->numericStatus = $rule['status']; if ($rule['status'] == self::SCANRESULT_CLEAN) { $this->details = ''; } else { $this->details = isset($matches[1]) ? $matches[1] : 'unknown'; } break; } } if (!$isMatched) { $this->numericStatus = self::SCANRESULT_UNCHECKED; $this->details = 'No matching rules. Please check antivirus rules.'; } } else { // Executable mode $query = \OCP\DB::prepare('SELECT * FROM `*PREFIX*files_antivirus_status` WHERE `status_type`=? and `result`=?'); $queryResult = $query->execute(array(self::STATUS_TYPE_CODE, $result)); $scanStatus = $queryResult->fetchRow(); if (is_array($scanStatus) && count($scanStatus)) { $this->numericStatus = $scanStatus['status']; } switch ($this->numericStatus) { case self::SCANRESULT_INFECTED: $report = array(); $rawResponse = explode("\n", $rawResponse); foreach ($rawResponse as $line) { if (preg_match('/.*: (.*) FOUND\\s*$/', $line, $matches)) { $report[] = $matches[1]; } } $this->details = implode(', ', $report); break; case self::SCANRESULT_UNCHECKED: $this->details = isset($scanStatus['description']) ? $scanStatus['description'] : 'No matching rule for exit code ' . $this->numericStatus . '. Please check antivirus rules configuration.'; } } //Log switch ($this->numericStatus) { case self::SCANRESULT_CLEAN: \OCP\Util::writeLog('files_antivirus', 'Result CLEAN!', \OCP\Util::DEBUG); break; case self::SCANRESULT_INFECTED: \OCP\Util::writeLog('files_antivirus', 'Virus(es) found: ' . $this->details, \OCP\Util::WARN); break; default: \OCP\Util::writeLog('files_antivirus', 'File could not be scanned. Details: ' . $this->details, \OCP\Util::WARN); } }
/** * get some information from a given share * @param int $shareID * @return array with: item_source, share_type, share_with, item_type, permissions */ private static function getShareFromId($shareID) { $sql = 'SELECT `file_source`, `item_source`, `share_type`, `share_with`, `item_type`, `permissions`, `stime` FROM `*PREFIX*share` WHERE `id` = ?'; $args = array($shareID); $query = \OCP\DB::prepare($sql); $result = $query->execute($args); if (\OCP\DB::isError($result)) { \OCP\Util::writeLog('files_sharing', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); return null; } if ($share = $result->fetchRow()) { return $share; } return null; }
private function createAddressBookURI($displayname, $userid = null) { $userid = $userid ? $userid : \OCP\User::getUser(); $name = str_replace(' ', '_', strtolower($displayname)); try { $stmt = \OCP\DB::prepare('SELECT `uri` FROM `' . $this->addressBooksTableName . '` WHERE `userid` = ? '); $result = $stmt->execute(array($userid)); if (\OCP\DB::isError($result)) { \OCP\Util::writeLog('contacts', __METHOD__ . 'DB error: ' . \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); return $name; } } catch (Exception $e) { \OCP\Util::writeLog('contacts', __METHOD__ . ' exception: ' . $e->getMessage(), \OCP\Util::ERROR); return $name; } $uris = array(); while ($row = $result->fetchRow()) { $uris[] = $row['uri']; } $newname = $name; $i = 1; while (in_array($newname, $uris)) { $newname = $name . $i; $i = $i + 1; } return $newname; }
/** * returns the error code and message as a string for logging * works with DoctrineException * @param mixed $error * @return string */ public static function getErrorMessage($error) { return \OC_DB::getErrorMessage($error); }
/** * @param string $pattern * @param string[] $searchProperties * @param $options * @return array|false */ public function search($pattern, $searchProperties, $options) { $propTable = '*PREFIX*conplus_cards_properties'; $contTable = '*PREFIX*conplus_cards'; $addrTable = '*PREFIX*conplus_addressbooks'; $results = array(); /** * This query will fetch all contacts which match the $searchProperties * It will look up the addressbookid of the contact and the user id of the owner of the contact app */ $query = <<<SQL \t\t\tSELECT \t\t\t\tDISTINCT \t\t\t\t`{$propTable}`.`contactid`, \t\t\t\t`{$contTable}`.`addressbookid`, \t\t\t\t`{$addrTable}`.`userid` \t\t\tFROM \t\t\t\t`{$propTable}` \t\t\tINNER JOIN \t\t\t\t`{$contTable}` \t\t\tON `{$contTable}`.`id` = `{$propTable}`.`contactid` \t\t\t\tINNER JOIN `{$addrTable}` \t\t\tON `{$addrTable}`.id = `{$contTable}`.addressbookid \t\t\tWHERE \t\t\t\t(`{$contTable}`.addressbookid = ?) AND \t\t\t\t( SQL; $params = array(); $params[] = $this->getKey(); foreach ($searchProperties as $property) { $params[] = $property; $params[] = '%' . $pattern . '%'; $query .= '(`name` = ? AND `value` ILIKE ?) OR '; } $query = substr($query, 0, strlen($query) - 4); $query .= ')'; $stmt = \OCP\DB::prepare($query); $result = $stmt->execute($params); if (\OCP\DB::isError($result)) { \OCP\Util::writeLog('contactsplus', __METHOD__ . 'DB error: ' . \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); return false; } $j = []; while ($row = $result->fetchRow()) { $id = $row['contactid']; //$addressbookKey = $row['addressbookid']; $vcard = App::getContactVCard($id); $contact = VCard::structureContact($vcard); $j['data'] = $contact; $j['data']['id'] = $id; $j['data']['metadata'] = $row; $j['data']['photo'] = false; if (isset($vcard->BDAY)) { $j['data']['birthday'] = $vcard->BDAY; } if (isset($vcard->PHOTO) || isset($vcard->LOGO)) { $j['data']['photo'] = true; $url = \OC::$server->getURLGenerator()->linkToRoute('contactsplus.contacts.getContactPhoto', array('id' => $id)); $url = \OC::$server->getURLGenerator()->getAbsoluteURL($url); $j['data']['PHOTO'] = "uri:{$url}"; } $results[] = $this->convertToSearchResult($j); } return $results; }
/** * @brief Move card(s) to an address book * @param integer $aid Address book id * @param $id Array or integer of cards to be moved. * @return boolean * */ public static function moveToAddressBook($aid, $id, $isAddressbook = false) { Addressbook::find($aid); $addressbook = Addressbook::find($aid); if ($addressbook['userid'] != \OCP\User::getUser()) { $sharedAddressbook = \OCP\Share::getItemSharedWithBySource('addressbook', $aid); if (!$sharedAddressbook || !($sharedAddressbook['permissions'] & \OCP\PERMISSION_CREATE)) { return false; } } if (is_array($id)) { foreach ($id as $index => $cardId) { $card = self::find($cardId); if (!$card) { unset($id[$index]); } $oldAddressbook = Addressbook::find($card['addressbookid']); if ($oldAddressbook['userid'] != \OCP\User::getUser()) { $sharedContact = \OCP\Share::getItemSharedWithBySource('contact', $cardId, \OCP\Share::FORMAT_NONE, null, true); if (!$sharedContact || !($sharedContact['permissions'] & \OCP\PERMISSION_DELETE)) { unset($id[$index]); } } } $id_sql = join(',', array_fill(0, count($id), '?')); $prep = 'UPDATE `*PREFIX*contacts_cards` SET `addressbookid` = ? WHERE `id` IN (' . $id_sql . ')'; try { $stmt = \OCP\DB::prepare($prep); //$aid = array($aid); $vals = array_merge((array) $aid, $id); $result = $stmt->execute($vals); if (\OC_DB::isError($result)) { \OC_Log::write('contacts', __METHOD__ . 'DB error: ' . \OC_DB::getErrorMessage($result), \OC_Log::ERROR); return false; } } catch (\Exception $e) { \OCP\Util::writeLog('contacts', __METHOD__ . ', exception: ' . $e->getMessage(), \OCP\Util::ERROR); \OCP\Util::writeLog('contacts', __METHOD__ . ', ids: ' . join(',', $vals), \OCP\Util::DEBUG); \OCP\Util::writeLog('contacts', __METHOD__ . ', SQL:' . $prep, \OCP\Util::DEBUG); return false; } } else { $stmt = null; if ($isAddressbook) { $stmt = \OCP\DB::prepare('UPDATE `*PREFIX*contacts_cards` SET `addressbookid` = ? WHERE `addressbookid` = ?'); } else { $card = self::find($id); if (!$card) { return false; } $oldAddressbook = Addressbook::find($card['addressbookid']); if ($oldAddressbook['userid'] != \OCP\User::getUser()) { $sharedContact = \OCP\Share::getItemSharedWithBySource('contact', $id, \OCP\Share::FORMAT_NONE, null, true); if (!$sharedContact || !($sharedContact['permissions'] & \OCP\PERMISSION_DELETE)) { return false; } } $stmt = \OCP\DB::prepare('UPDATE `*PREFIX*contacts_cards` SET `addressbookid` = ? WHERE `id` = ?'); } try { $result = $stmt->execute(array($aid, $id)); if (\OC_DB::isError($result)) { \OC_Log::write('contacts', __METHOD__ . 'DB error: ' . \OC_DB::getErrorMessage($result), \OC_Log::ERROR); return false; } } catch (\Exception $e) { \OCP\Util::writeLog('contacts', __METHOD__ . ', exception: ' . $e->getMessage(), \OCP\Util::DEBUG); \OCP\Util::writeLog('contacts', __METHOD__ . ' id: ' . $id, \OCP\Util::DEBUG); return false; } } \OC_Hook::emit('\\OCA\\Contacts\\VCard', 'post_moveToAddressbook', array('aid' => $aid, 'id' => $id)); Addressbook::touch($aid); return true; }
/** * Update the contact property index. * * If vcard is null the properties for that contact will be purged. * If it is a valid object the old properties will first be purged * and the current properties indexed. * * @param string $contactId * @param VCard|null $vCard */ public static function updateIndex($contactId, $vCard = null) { self::purgeIndexes(array($contactId)); if (is_null($vCard)) { return; } if (!isset(self::$updateindexstmt)) { self::$updateindexstmt = \OCP\DB::prepare('INSERT INTO `' . self::$indexTableName . '` ' . '(`userid`, `contactid`,`name`,`value`,`preferred`) VALUES(?,?,?,?,?)'); } foreach ($vCard->children as $property) { if (!in_array($property->name, self::$indexProperties)) { continue; } $preferred = 0; foreach ($property->parameters as $parameter) { if ($parameter->name == 'TYPE' && strtoupper($parameter->getValue()) == 'PREF') { $preferred = 1; break; } } try { $result = self::$updateindexstmt->execute(array(\OC::$server->getUserSession()->getUser()->getUId(), $contactId, $property->name, substr($property->getValue(), 0, 254), $preferred)); if (\OCP\DB::isError($result)) { \OCP\Util::writeLog('contacts', __METHOD__ . 'DB error: ' . \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); return false; } } catch (\Exception $e) { \OCP\Util::writeLog('contacts', __METHOD__ . ', exception: ' . $e->getMessage(), \OCP\Util::ERROR); return false; } } }
public static function updateDBProperties($contactid, $vcard = null) { $stmt = \OCP\DB::prepare('DELETE FROM `*PREFIX*contacts_cards_properties` WHERE `contactid` = ?'); try { $stmt->execute(array($contactid)); } catch (\Exception $e) { \OCP\Util::writeLog('contacts', __METHOD__ . ', exception: ' . $e->getMessage(), \OCP\Util::ERROR); \OCP\Util::writeLog('contacts', __METHOD__ . ', id: ' . $id, \OCP\Util::DEBUG); throw new \Exception(App::$l10n->t('There was an error deleting properties for this contact.')); } if (is_null($vcard)) { return; } $stmt = \OCP\DB::prepare('INSERT INTO `*PREFIX*contacts_cards_properties` ' . '(`userid`, `contactid`,`name`,`value`,`preferred`) VALUES(?,?,?,?,?)'); foreach ($vcard->children as $property) { if (!in_array($property->name, self::$index_properties)) { continue; } $preferred = false; foreach ($property->parameters as $parameter) { if ($parameter->name == 'TYPE' && strtoupper($parameter->value) == 'PREF') { $preferred = true; break; } } try { $result = $stmt->execute(array(\OCP\User::getUser(), $contactid, $property->name, $property->value, $preferred)); if (\OC_DB::isError($result)) { \OCP\Util::writeLog('contacts', __METHOD__ . 'DB error: ' . \OC_DB::getErrorMessage($result), \OC_Log::ERROR); return false; } } catch (\Exception $e) { \OCP\Util::writeLog('contacts', __METHOD__ . ', exception: ' . $e->getMessage(), \OCP\Util::ERROR); \OCP\Util::writeLog('contacts', __METHOD__ . ', aid: ' . $aid . ' uri' . $uri, \OCP\Util::DEBUG); return false; } } }
/** * @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`, `token`'; } else { $select = '`id`, `item_type`, `item_source`, `parent`, `share_type`, `share_with`, `permissions`, `stime`, `file_source`, `expiration`, `token`'; } } 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`, `token`'; } } else { $select = '*'; } } } $root = strlen($root); $query = \OC_DB::prepare('SELECT ' . $select . ' FROM `*PREFIX*share` ' . $where, $queryLimit); $result = $query->execute($queryArgs); if (\OC_DB::isError($result)) { \OC_Log::write('OCP\\Share', \OC_DB::getErrorMessage($result) . ', select=' . $select . ' where=' . $where, \OC_Log::ERROR); } $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'] & PERMISSION_SHARE && (int) $row['permissions'] & 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(); }
/** * Returns the list of active addressbooks for a specific user. * * @param string $userid * @return array */ public function getAddressBooksForUser(array $options = array()) { try { if (!isset(self::$preparedQueries['addressbooksforuser'])) { $sql = 'SELECT `configkey` from *PREFIX*preferences where `configkey` like ?'; $configkeyPrefix = $this->name . "_%_uri"; self::$preparedQueries['addressbooksforuser'] = \OCP\DB::prepare($sql); $result = self::$preparedQueries['addressbooksforuser']->execute(array($configkeyPrefix)); if (\OC_DB::isError($result)) { \OCP\Util::write('contacts', __METHOD__ . 'DB error: ' . \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); return $this->addressbooks; } $this->addressbooks = array(); while ($row = $result->fetchRow()) { $id = str_replace("_uri", "", str_replace($this->name . "_", "", $row['configkey'])); $this->addressbooks[] = self::getAddressBook($id); } return $this->addressbooks; } } catch (\Exception $e) { \OC_Log::write('contacts', __METHOD__ . ' exception: ' . $e->getMessage(), \OCP\Util::ERROR); return $this->addressbooks; } }
/** * Add an album to the database * * @param string $name * @param integer $artist * @return integer the album_id of the added artist */ public function addAlbum($name, $artist) { $name = trim($name); if ($name == '') { return 0; } //check if the album is already in the database $albumId = self::getAlbumId($name, $artist); if ($albumId != 0) { return $albumId; } else { $stmt = \OCP\DB::prepare('INSERT INTO `*PREFIX*media_albums` (`album_name` ,`album_artist`) VALUES (?, ?)'); if (!\OCP\DB::isError($stmt)) { $result = $stmt->execute(array($name, $artist)); if (\OCP\DB::isError($result)) { \OC_Log::write('OC_MEDIA_COLLECTION', 'could not add album: ' . \OC_DB::getErrorMessage($result), \OC_Log::ERROR); } } else { \OC_Log::write('OC_MEDIA_COLLECTION', 'could not add album: ' . \OC_DB::getErrorMessage($stmt), \OC_Log::ERROR); } return $this->getAlbumId($name, $artist); } }
/** * counts the users in the database * * @return int | bool */ public function countUsers() { $query = OC_DB::prepare('SELECT COUNT(*) FROM `*PREFIX*users`'); $result = $query->execute(); if (OC_DB::isError($result)) { OC_Log::write('core', OC_DB::getErrorMessage($result), OC_Log::ERROR); return false; } return $result->fetchOne(); }
/** * @brief Delete categories from the db and from all the vobject supplied * @param $names An array of categories to delete * @param $objects An array of arrays with [id,vobject] (as text) pairs suitable for updating the apps object table. */ public function delete($names, array &$objects = null) { if (!is_array($names)) { $names = array($names); } OC_Log::write('core', __METHOD__ . ', before: ' . print_r($this->categories, true), OC_Log::DEBUG); foreach ($names as $name) { $id = null; OC_Log::write('core', __METHOD__ . ', ' . $name, OC_Log::DEBUG); if ($this->hasCategory($name)) { $id = $this->array_searchi($name, $this->categories); unset($this->categories[$id]); } try { $stmt = OCP\DB::prepare('DELETE FROM `' . self::CATEGORY_TABLE . '` WHERE ' . '`uid` = ? AND `type` = ? AND `category` = ?'); $result = $stmt->execute(array($this->user, $this->type, $name)); if (OC_DB::isError($result)) { OC_Log::write('core', __METHOD__ . 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR); } } catch (Exception $e) { OCP\Util::writeLog('core', __METHOD__ . ', exception: ' . $e->getMessage(), OCP\Util::ERROR); } if (!is_null($id) && $id !== false) { try { $sql = 'DELETE FROM `' . self::RELATION_TABLE . '` ' . 'WHERE `categoryid` = ?'; $stmt = OCP\DB::prepare($sql); $result = $stmt->execute(array($id)); if (OC_DB::isError($result)) { OC_Log::write('core', __METHOD__ . 'DB error: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR); } } catch (Exception $e) { OCP\Util::writeLog('core', __METHOD__ . ', exception: ' . $e->getMessage(), OCP\Util::ERROR); return false; } } } OC_Log::write('core', __METHOD__ . ', after: ' . print_r($this->categories, true), OC_Log::DEBUG); if (!is_null($objects)) { foreach ($objects as $key => &$value) { $vobject = OC_VObject::parse($value[1]); if (!is_null($vobject)) { $object = null; $componentname = ''; if (isset($vobject->VEVENT)) { $object = $vobject->VEVENT; $componentname = 'VEVENT'; } else { if (isset($vobject->VTODO)) { $object = $vobject->VTODO; $componentname = 'VTODO'; } else { if (isset($vobject->VJOURNAL)) { $object = $vobject->VJOURNAL; $componentname = 'VJOURNAL'; } else { $object = $vobject; } } } $categories = $object->getAsArray('CATEGORIES'); foreach ($names as $name) { $idx = $this->array_searchi($name, $categories); if ($idx !== false) { OC_Log::write('core', __METHOD__ . ', unsetting: ' . $categories[$this->array_searchi($name, $categories)], OC_Log::DEBUG); unset($categories[$this->array_searchi($name, $categories)]); } } $object->setString('CATEGORIES', implode(',', $categories)); if ($vobject !== $object) { $vobject[$componentname] = $object; } $value[1] = $vobject->serialize(); $objects[$key] = $value; } else { OC_Log::write('core', __METHOD__ . ', unable to parse. ID: ' . $value[0] . ', ' . substr($value[1], 0, 50) . '(...)', OC_Log::DEBUG); } } } }
/** * @param $id * @return mixed */ public function delete($id) { try { $query = 'SELECT COUNT(*) as `count` FROM `*PREFIX*contacts_cards` WHERE `id` = ? AND `addressbookid` = ?'; $stmt = \OCP\DB::prepare($query); $result = $stmt->execute(array($id, $this->id)); if (\OCP\DB::isError($result)) { \OCP\Util::writeLog('contacts', __METHOD__ . 'DB error: ' . \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); return false; } if ((int) $result['count'] === 0) { \OCP\Util::writeLog('contacts', __METHOD__ . 'Contact with id ' . $id . 'doesn\'t belong to addressbook with id ' . $this->id, \OCP\Util::ERROR); return false; } } catch (\Exception $e) { \OCP\Util::writeLog('contacts', __METHOD__ . ', exception: ' . $e->getMessage(), \OCP\Util::ERROR); return false; } return VCard::delete($id); }
/** * Create a unique URI based on the display name. * * @param string $displayName * @return string */ private function createAddressBookURI($displayName) { $name = str_replace(' ', '_', strtolower($displayName)); try { $stmt = $this->getPreparedQuery('addressbookuris'); $result = $stmt->execute(array($this->userid)); if (\OCP\DB::isError($result)) { \OCP\Util::writeLog('contacts', __METHOD__ . 'DB error: ' . \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); return $name; } } catch (\Exception $e) { \OCP\Util::writeLog('contacts', __METHOD__ . ' exception: ' . $e->getMessage(), \OCP\Util::ERROR); return $name; } $uris = array(); while ($row = $result->fetchRow()) { $uris[] = $row['uri']; } $newname = $name; $i = 1; while (in_array($newname, $uris)) { $newname = $name . $i; $i = $i + 1; } return $newname; }
/** * @brief check if a user exists * @param string $uid the username * @return boolean */ public function userExists($uid) { $query = OC_DB::prepare('SELECT * FROM `*PREFIX*users` WHERE LOWER(`uid`) = LOWER(?)'); $result = $query->execute(array($uid)); if (OC_DB::isError($result)) { OC_Log::write('core', OC_DB::getErrorMessage($result), OC_Log::ERROR); return false; } return $result->numRows() > 0; }
private function setHashAndStatus($data) { $hash = sha1(json_encode($data)); // hash exists in DB ? $sql = 'SELECT * FROM `*PREFIX*ocDashboard_usedHashs` WHERE usedHash = ? AND widget = ? AND user = ? LIMIT 1;'; $params = Array($hash,$this->id,$this->user); $query = \OCP\DB::prepare($sql); $result = $query->execute($params)->fetchRow(); //if (\OCP\DB::isError($result)) { // \OCP\Util::writeLog('ocDashboard',"Could not find hash in db.", \OCP\Util::WARN); // \OCP\Util::writeLog('ocDashboard', \OC_DB::getErrorMessage($result), \OC_Log::ERROR); //} $all = $query->execute($params)->fetchAll(); //var_dump($all); $resultNum = count($all); // if not in DB, write to DB if( $resultNum == 0 ) { $sql2 = 'INSERT INTO `*PREFIX*ocDashboard_usedHashs` (usedHash,widget,user,timestamp) VALUES (?,?,?,?); '; $params = Array($hash,$this->id,$this->user,time()); $query2 = \OCP\DB::prepare($sql2); $result2 = $query2->execute($params); if (\OCP\DB::isError($result2)) { \OCP\Util::writeLog('ocDashboard',"Could not write hash to db.", \OCP\Util::WARN); \OCP\Util::writeLog('ocDashboard', \OC_DB::getErrorMessage($result), \OC_Log::ERROR); } $this->status = 2; } else { $this->status = 0; } }
private function prepareEvents() { $sql = "SELECT \n\t\t\t\t\tDATEDIFF(obj.startdate, obj.enddate) as diff, \n\t\t\t\t\tcal.displayname as calendar, \n\t\t\t\t\tobj.summary as title, \n\t\t\t\t\tcal.calendarcolor as color, \n\t\t\t\t\tIF(obj.repeating=0,obj.startdate,rep.startdate) as eventStart, \n\t\t\t\t\tIF(repeating=0,obj.enddate,rep.enddate) as eventEnd,\n\t\t\t\t\tobj.calendardata as data\n\t\t\t\tFROM \n\t\t\t\t\t`*PREFIX*clndr_objects` obj \n\t\t\t\t\t\tLEFT JOIN \n\t\t\t\t\t`*PREFIX*clndr_repeat` rep ON obj.id = rep.eventid\n\t\t\t\t\t\tJOIN\n\t\t\t\t\t`*PREFIX*clndr_calendars` cal on cal.id = obj.calendarid\n\t\t\t\tWHERE obj.objecttype = 'VEVENT' AND\n\t\t\t\t\tuserid = ? AND \n\t\t\t\t\t(\n\t\t\t\t\t\tDATE(obj.enddate) >= CURRENT_DATE\n\t\t\t\t\tOR \n\t\t\t\t\t\tDATE(rep.enddate) >= CURRENT_DATE\n\t\t\t\t\t)\n\t\t\t\tORDER BY\n\t\t\t\t\teventStart\n\t\t\t\tLIMIT " . $this->numEvents; $params = array($this->user); $query = \OCP\DB::prepare($sql); $result = $query->execute($params); if (\OCP\DB::isError($result)) { $this->errorMsg = "SQL Error"; \OCP\Util::writeLog('ocDashboard', \OC_DB::getErrorMessage($result), \OC_Log::ERROR); } while ($row = $result->fetchRow()) { // with timezone $row['start'] = strtotime($row['eventStart']) + $this->timezoneAdd * 60 * 60; $row['end'] = strtotime($row['eventEnd']) + $this->timezoneAdd * 60 * 60; //withour timezone $row['origStart'] = strtotime($row['eventStart']); $row['origEnd'] = strtotime($row['eventEnd']); $this->events[] = $row; } }
/** * checks if a user is enabled * @param string $userid * @return bool */ public static function isEnabled($userid) { $sql = 'SELECT `userid` FROM `*PREFIX*preferences`' . ' WHERE `userid` = ? AND `appid` = ? AND `configkey` = ? AND `configvalue` = ?'; if (OC_Config::getValue('dbtype', 'sqlite') === 'oci') { //FIXME oracle hack $sql = 'SELECT `userid` FROM `*PREFIX*preferences`' . ' WHERE `userid` = ? AND `appid` = ? AND `configkey` = ? AND to_char(`configvalue`) = ?'; } $stmt = OC_DB::prepare($sql); if (!OC_DB::isError($stmt)) { $result = $stmt->execute(array($userid, 'core', 'enabled', 'false')); if (!OC_DB::isError($result)) { return $result->numRows() ? false : true; } else { OC_Log::write('OC_User', 'could not check if enabled: ' . OC_DB::getErrorMessage($result), OC_Log::ERROR); } } else { OC_Log::write('OC_User', 'could not check if enabled: ' . OC_DB::getErrorMessage($stmt), OC_Log::ERROR); } return false; }
/** * @brief Checks if an addressbook is active. * @param integer $id ID of the address book. * @return boolean */ public static function isActive($id) { $sql = 'SELECT `active` FROM `*PREFIX*contacts_addressbooks` WHERE `id` = ?'; try { $stmt = \OCP\DB::prepare($sql); $result = $stmt->execute(array($id)); if (\OC_DB::isError($result)) { \OC_Log::write('contacts', __METHOD__ . 'DB error: ' . \OC_DB::getErrorMessage($result), \OC_Log::ERROR); return false; } $row = $result->fetchRow(); return (bool) $row['active']; } catch (Exception $e) { \OCP\Util::writeLog('contacts', __METHOD__ . ', exception: ' . $e->getMessage(), \OCP\Util::ERROR); return false; } }
/** * get the list of all unindexed files for the user * * @return array */ public static function getUnindexed() { $files = array(); $absoluteRoot = Filesystem::getView()->getAbsolutePath('/'); $mounts = Filesystem::getMountPoints($absoluteRoot); $mount = Filesystem::getMountPoint($absoluteRoot); if (!in_array($mount, $mounts)) { $mounts[] = $mount; } $query = \OC_DB::prepare(' SELECT `*PREFIX*filecache`.`fileid` FROM `*PREFIX*filecache` LEFT JOIN `*PREFIX*lucene_status` ON `*PREFIX*filecache`.`fileid` = `*PREFIX*lucene_status`.`fileid` WHERE `storage` = ? AND `status` IS NULL OR `status` = ? '); foreach ($mounts as $mount) { if (is_string($mount)) { $storage = Filesystem::getStorage($mount); } else { if ($mount instanceof \OC\Files\Mount\Mount) { $storage = $mount->getStorage(); } else { $storage = null; Util::writeLog('search_lucene', 'expected string or instance of \\OC\\Files\\Mount\\Mount got ' . json_encode($mount), Util::DEBUG); } } //only index local files for now if ($storage instanceof \OC\Files\Storage\Local) { $cache = $storage->getCache(); $numericId = $cache->getNumericStorageId(); $result = $query->execute(array($numericId, 'N')); if (\OC_DB::isError($result)) { Util::writeLog('search_lucene', 'failed to find unindexed files: ' . \OC_DB::getErrorMessage($result), Util::WARN); return false; } while ($row = $result->fetchRow()) { $files[] = $row['fileid']; } } } return $files; }
/** * 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) * @param bool TODO (optional) * @prams bool check expire date * @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, $checkExpireDate = true) { if (!self::isEnabled()) { if ($limit == 1 || isset($uidOwner) && isset($item)) { return false; } else { return array(); } } $backend = self::getBackend($itemType); $collectionTypes = false; // 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') { if (!is_null($uidOwner)) { $root = \OC\Files\Filesystem::getRoot(); } else { $root = ''; } $where = 'INNER JOIN `*PREFIX*filecache` ON `file_source` = `*PREFIX*filecache`.`fileid`'; 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 (\OC_Appconfig::getValue('core', 'shareapi_allow_links', 'yes') !== 'yes') { $where .= ' AND `share_type` != ?'; $queryArgs[] = self::SHARE_TYPE_LINK; } 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\Files\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`, `item_source`, `*PREFIX*share`.`parent`,' . ' `share_type`, `file_source`, `path`, `expiration`, `storage`, `share_with`, `mail_send`, `uid_owner`'; } else { $select = '`id`, `item_type`, `item_source`, `parent`, `share_type`, `share_with`, `expiration`, `mail_send`, `uid_owner`'; } } else { if (isset($uidOwner)) { if ($itemType == 'file' || $itemType == 'folder') { $select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `*PREFIX*share`.`parent`,' . ' `share_type`, `share_with`, `file_source`, `path`, `permissions`, `stime`,' . ' `expiration`, `token`, `storage`, `mail_send`, `uid_owner`'; } else { $select = '`id`, `item_type`, `item_source`, `parent`, `share_type`, `share_with`, `permissions`,' . ' `stime`, `file_source`, `expiration`, `token`, `mail_send`, `uid_owner`'; } } else { if ($fileDependent) { if (($itemType == 'file' || $itemType == 'folder') && $format == \OC_Share_Backend_File::FORMAT_GET_FOLDER_CONTENTS || $format == \OC_Share_Backend_File::FORMAT_FILE_APP_ROOT) { $select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `*PREFIX*share`.`parent`, `uid_owner`, ' . '`share_type`, `share_with`, `file_source`, `path`, `file_target`, ' . '`permissions`, `expiration`, `storage`, `*PREFIX*filecache`.`parent` as `file_parent`, ' . '`name`, `mtime`, `mimetype`, `mimepart`, `size`, `unencrypted_size`, `encrypted`, `etag`, `mail_send`'; } 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`, `token`, `storage`, `mail_send`'; } } else { $select = '*'; } } } $root = strlen($root); $query = \OC_DB::prepare('SELECT ' . $select . ' FROM `*PREFIX*share` ' . $where, $queryLimit); $result = $query->execute($queryArgs); if (\OC_DB::isError($result)) { \OC_Log::write('OCP\\Share', \OC_DB::getErrorMessage($result) . ', select=' . $select . ' where=' . $where, \OC_Log::ERROR); } $items = array(); $targets = array(); $switchedItems = array(); $mounts = array(); while ($row = $result->fetchRow()) { if (isset($row['id'])) { $row['id'] = (int) $row['id']; } if (isset($row['share_type'])) { $row['share_type'] = (int) $row['share_type']; } if (isset($row['parent'])) { $row['parent'] = (int) $row['parent']; } if (isset($row['file_parent'])) { $row['file_parent'] = (int) $row['file_parent']; } if (isset($row['file_source'])) { $row['file_source'] = (int) $row['file_source']; } if (isset($row['permissions'])) { $row['permissions'] = (int) $row['permissions']; } if (isset($row['storage'])) { $row['storage'] = (int) $row['storage']; } if (isset($row['stime'])) { $row['stime'] = (int) $row['stime']; } // 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 (isset($items[$id]) && $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'] & PERMISSION_SHARE && (int) $row['permissions'] & PERMISSION_SHARE) { $items[$row['id']] = $items[$id]; $switchedItems[$id] = $row['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'])) { // FIXME: Doesn't always construct the correct path, example: // Folder '/a/b', share '/a' and '/a/b' to user2 // user2 reshares /Shared/b and ask for share status of /Shared/a/b // expected result: path=/Shared/a/b; actual result /Shared/b because of the parent $query = \OC_DB::prepare('SELECT `file_target` FROM `*PREFIX*share` WHERE `id` = ?'); $parentResult = $query->execute(array($row['parent'])); if (\OC_DB::isError($result)) { \OC_Log::write('OCP\\Share', 'Can\'t select parent: ' . \OC_DB::getErrorMessage($result) . ', select=' . $select . ' where=' . $where, \OC_Log::ERROR); } else { $parentRow = $parentResult->fetchRow(); $tmpPath = '/Shared' . $parentRow['file_target']; // find the right position where the row path continues from the target path $pos = strrpos($row['path'], $parentRow['file_target']); $subPath = substr($row['path'], $pos); $splitPath = explode('/', $subPath); foreach (array_slice($splitPath, 2) as $pathPart) { $tmpPath = $tmpPath . '/' . $pathPart; } $row['path'] = $tmpPath; } } else { if (!isset($mounts[$row['storage']])) { $mountPoints = \OC\Files\Filesystem::getMountByNumericId($row['storage']); if (is_array($mountPoints)) { $mounts[$row['storage']] = current($mountPoints); } } if ($mounts[$row['storage']]) { $path = $mounts[$row['storage']]->getMountPoint() . $row['path']; $row['path'] = substr($path, $root); } } } if ($checkExpireDate) { if (self::expireItem($row)) { continue; } } // Check if resharing is allowed, if not remove share permission if (isset($row['permissions']) && !self::isResharingAllowed()) { $row['permissions'] &= ~PERMISSION_SHARE; } // Add display names to result if (isset($row['share_with']) && $row['share_with'] != '') { $row['share_with_displayname'] = \OCP\User::getDisplayName($row['share_with']); } if (isset($row['uid_owner']) && $row['uid_owner'] != '') { $row['displayname_owner'] = \OCP\User::getDisplayName($row['uid_owner']); } $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[$column] == $item && ($row['item_type'] == $itemType || $itemType == 'file')) { 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 { $meta = \OC\Files\Filesystem::getFileInfo($child['file_path']); $childItem['file_source'] = $meta['fileid']; } $childItem['file_target'] = \OC\Files\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 $toRemove = $row['id']; if (array_key_exists($toRemove, $switchedItems)) { $toRemove = $switchedItems[$toRemove]; } unset($items[$toRemove]); } } if (!empty($collectionItems)) { $items = array_merge($items, $collectionItems); } if (empty($items) && $limit == 1) { return false; } if ($format == self::FORMAT_NONE) { return $items; } else { if ($format == self::FORMAT_STATUSES) { $statuses = array(); foreach ($items as $item) { if ($item['share_type'] == self::SHARE_TYPE_LINK) { $statuses[$item[$column]]['link'] = true; } else { if (!isset($statuses[$item[$column]])) { $statuses[$item[$column]]['link'] = false; } } if ($itemType == 'file' || $itemType == 'folder') { $statuses[$item[$column]]['path'] = $item['path']; } } return $statuses; } else { return $backend->formatItems($items, $format, $parameters); } } } else { if ($limit == 1 || isset($uidOwner) && isset($item)) { return false; } } return array(); }
/** * Get shared items from the database * @param string $itemType * @param string $item Item source or target (optional) * @param int $shareType SHARE_TYPE_USER, SHARE_TYPE_GROUP, SHARE_TYPE_LINK, $shareTypeUserAndGroups, or $shareTypeGroupUserUnique * @param string $shareWith User or group the item is being shared with * @param string $uidOwner User that is the owner of shared items (optional) * @param int $format Format to convert items to with formatItems() (optional) * @param mixed $parameters to pass to formatItems() (optional) * @param int $limit Number of items to return, -1 to return all matches (optional) * @param boolean $includeCollections Include collection item types (optional) * @param boolean $itemShareWithBySource (optional) * @param boolean $checkExpireDate * @return array * * See public functions getItem(s)... for parameter usage * */ public static function getItems($itemType, $item = null, $shareType = null, $shareWith = null, $uidOwner = null, $format = self::FORMAT_NONE, $parameters = null, $limit = -1, $includeCollections = false, $itemShareWithBySource = false, $checkExpireDate = true) { if (!self::isEnabled()) { return array(); } $backend = self::getBackend($itemType); $collectionTypes = false; // 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') { if (!is_null($uidOwner)) { $root = \OC\Files\Filesystem::getRoot(); } else { $root = ''; } $where = 'INNER JOIN `*PREFIX*filecache` ON `file_source` = `*PREFIX*filecache`.`fileid` '; if (!isset($item)) { $where .= ' AND `file_target` IS NOT NULL '; } $where .= 'INNER JOIN `*PREFIX*storages` ON `numeric_id` = `*PREFIX*filecache`.`storage` '; $fileDependent = true; $queryArgs = array(); } else { $fileDependent = false; $root = ''; $collectionTypes = self::getCollectionItemTypes($itemType); if ($includeCollections && !isset($item) && $collectionTypes) { // 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 (\OC::$server->getAppConfig()->getValue('core', 'shareapi_allow_links', 'yes') !== 'yes') { $where .= ' AND `share_type` != ?'; $queryArgs[] = self::SHARE_TYPE_LINK; } if (isset($shareType)) { // Include all user and group items if ($shareType == self::$shareTypeUserAndGroups && isset($shareWith)) { $where .= ' AND ((`share_type` in (?, ?) AND `share_with` = ?) '; $queryArgs[] = self::SHARE_TYPE_USER; $queryArgs[] = self::$shareTypeGroupUserUnique; $queryArgs[] = $shareWith; $groups = \OC_Group::getUserGroups($shareWith); if (!empty($groups)) { $placeholders = join(',', array_fill(0, count($groups), '?')); $where .= ' OR (`share_type` = ? AND `share_with` IN (' . $placeholders . ')) '; $queryArgs[] = self::SHARE_TYPE_GROUP; $queryArgs = array_merge($queryArgs, $groups); } $where .= ')'; // 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 ($fileDependent) { $column = 'file_source'; } else { $column = 'item_source'; } } else { if ($fileDependent) { $column = 'file_target'; } else { $column = 'item_target'; } } if (isset($item)) { $collectionTypes = self::getCollectionItemTypes($itemType); if ($includeCollections && $collectionTypes && !in_array('folder', $collectionTypes)) { $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 ($fileDependent) { $where .= ' `file_source` = ?'; $column = 'file_source'; } else { $where .= ' `item_source` = ?'; $column = 'item_source'; } } else { if ($fileDependent) { $where .= ' `file_target` = ?'; $item = \OC\Files\Filesystem::normalizePath($item); } else { $where .= ' `item_target` = ?'; } } $queryArgs[] = $item; if ($includeCollections && $collectionTypes && !in_array('folder', $collectionTypes)) { $placeholders = join(',', array_fill(0, count($collectionTypes), '?')); $where .= ' OR `item_type` IN (' . $placeholders . '))'; $queryArgs = array_merge($queryArgs, $collectionTypes); } } if ($shareType == self::$shareTypeUserAndGroups && $limit === 1) { // 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'; } else { $where .= ' ORDER BY `*PREFIX*share`.`id` ASC'; } if ($limit != -1 && !$includeCollections) { // The limit must be at least 3, because filtering needs to be done if ($limit < 3) { $queryLimit = 3; } else { $queryLimit = $limit; } } else { $queryLimit = null; } $select = self::createSelectStatement($format, $fileDependent, $uidOwner); $root = strlen($root); $query = \OC_DB::prepare('SELECT ' . $select . ' FROM `*PREFIX*share` ' . $where, $queryLimit); $result = $query->execute($queryArgs); if (\OC_DB::isError($result)) { \OCP\Util::writeLog('OCP\\Share', \OC_DB::getErrorMessage() . ', select=' . $select . ' where=', \OCP\Util::ERROR); } $items = array(); $targets = array(); $switchedItems = array(); $mounts = array(); while ($row = $result->fetchRow()) { self::transformDBResults($row); // Filter out duplicate group shares for users with unique targets if ($fileDependent && !self::isFileReachable($row['path'], $row['storage_id'])) { continue; } if ($row['share_type'] == self::$shareTypeGroupUserUnique && isset($items[$row['parent']])) { $row['share_type'] = self::SHARE_TYPE_GROUP; $row['unique_name'] = true; // remember that we use a unique name for this user $row['share_with'] = $items[$row['parent']]['share_with']; // if the group share was unshared from the user we keep the permission, otherwise // we take the permission from the parent because this is always the up-to-date // permission for the group share if ($row['permissions'] > 0) { $row['permissions'] = $items[$row['parent']]['permissions']; } // 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['id']])) { // Check if the same owner shared with the user twice // through a group and user share - this is allowed $id = $targets[$row['id']]; if (isset($items[$id]) && $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'] & \OCP\Constants::PERMISSION_SHARE && (int) $row['permissions'] & \OCP\Constants::PERMISSION_SHARE) { $items[$row['id']] = $items[$id]; $switchedItems[$id] = $row['id']; unset($items[$id]); $id = $row['id']; } $items[$id]['permissions'] |= (int) $row['permissions']; } continue; } elseif (!empty($row['parent'])) { $targets[$row['parent']] = $row['id']; } } } // Remove root from file source paths if retrieving own shared items if (isset($uidOwner) && isset($row['path'])) { if (isset($row['parent'])) { $query = \OC_DB::prepare('SELECT `file_target` FROM `*PREFIX*share` WHERE `id` = ?'); $parentResult = $query->execute(array($row['parent'])); if (\OC_DB::isError($result)) { \OCP\Util::writeLog('OCP\\Share', 'Can\'t select parent: ' . \OC_DB::getErrorMessage() . ', select=' . $select . ' where=' . $where, \OCP\Util::ERROR); } else { $parentRow = $parentResult->fetchRow(); $tmpPath = $parentRow['file_target']; // find the right position where the row path continues from the target path $pos = strrpos($row['path'], $parentRow['file_target']); $subPath = substr($row['path'], $pos); $splitPath = explode('/', $subPath); foreach (array_slice($splitPath, 2) as $pathPart) { $tmpPath = $tmpPath . '/' . $pathPart; } $row['path'] = $tmpPath; } } else { if (!isset($mounts[$row['storage']])) { $mountPoints = \OC\Files\Filesystem::getMountByNumericId($row['storage']); if (is_array($mountPoints) && !empty($mountPoints)) { $mounts[$row['storage']] = current($mountPoints); } } if (!empty($mounts[$row['storage']])) { $path = $mounts[$row['storage']]->getMountPoint() . $row['path']; $relPath = substr($path, $root); // path relative to data/user $row['path'] = rtrim($relPath, '/'); } } } if ($checkExpireDate) { if (self::expireItem($row)) { continue; } } // Check if resharing is allowed, if not remove share permission if (isset($row['permissions']) && !self::isResharingAllowed() | \OCP\Util::isSharingDisabledForUser()) { $row['permissions'] &= ~\OCP\Constants::PERMISSION_SHARE; } // Add display names to result $row['share_with_displayname'] = $row['share_with']; if (isset($row['share_with']) && $row['share_with'] != '' && $row['share_type'] === self::SHARE_TYPE_USER) { $row['share_with_displayname'] = \OCP\User::getDisplayName($row['share_with']); } else { if (isset($row['share_with']) && $row['share_with'] != '' && $row['share_type'] === self::SHARE_TYPE_REMOTE) { $addressBookEntries = \OC::$server->getContactsManager()->search($row['share_with'], ['CLOUD']); foreach ($addressBookEntries as $entry) { foreach ($entry['CLOUD'] as $cloudID) { if ($cloudID === $row['share_with']) { $row['share_with_displayname'] = $entry['FN']; } } } } } if (isset($row['uid_owner']) && $row['uid_owner'] != '') { $row['displayname_owner'] = \OCP\User::getDisplayName($row['uid_owner']); } if ($row['permissions'] > 0) { $items[$row['id']] = $row; } } // group items if we are looking for items shared with the current user if (isset($shareWith) && $shareWith === \OCP\User::getUser()) { $items = self::groupItems($items, $itemType); } if (!empty($items)) { $collectionItems = array(); foreach ($items as &$row) { // Return only the item instead of a 2-dimensional array if ($limit == 1 && $row[$column] == $item && ($row['item_type'] == $itemType || $itemType == 'file')) { if ($format == self::FORMAT_NONE) { return $row; } else { break; } } // Check if this is a collection of the requested item type if ($includeCollections && $collectionTypes && $row['item_type'] !== 'folder' && in_array($row['item_type'], $collectionTypes)) { if (($collectionBackend = self::getBackend($row['item_type'])) && $collectionBackend instanceof \OCP\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 \OCP\Share_Backend_File_Dependent) { if ($row['item_type'] == 'file' || $row['item_type'] == 'folder') { $childItem['file_source'] = $child['source']; } else { // TODO is this really needed if we already know that we use the file backend? $meta = \OC\Files\Filesystem::getFileInfo($child['file_path']); $childItem['file_source'] = $meta['fileid']; } $childItem['file_target'] = \OC\Files\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 $toRemove = $row['id']; if (array_key_exists($toRemove, $switchedItems)) { $toRemove = $switchedItems[$toRemove]; } unset($items[$toRemove]); } elseif ($includeCollections && $collectionTypes && in_array($row['item_type'], $collectionTypes)) { // FIXME: Thats a dirty hack to improve file sharing performance, // see github issue #10588 for more details // Need to find a solution which works for all back-ends $collectionBackend = self::getBackend($row['item_type']); $sharedParents = $collectionBackend->getParents($row['item_source']); foreach ($sharedParents as $parent) { $collectionItems[] = $parent; } } } if (!empty($collectionItems)) { $collectionItems = array_unique($collectionItems, SORT_REGULAR); $items = array_merge($items, $collectionItems); } // filter out invalid items, these can appear when subshare entries exist // for a group in which the requested user isn't a member any more $items = array_filter($items, function ($item) { return $item['share_type'] !== self::$shareTypeGroupUserUnique; }); return self::formatResult($items, $column, $backend, $format, $parameters); } elseif ($includeCollections && $collectionTypes && in_array('folder', $collectionTypes)) { // FIXME: Thats a dirty hack to improve file sharing performance, // see github issue #10588 for more details // Need to find a solution which works for all back-ends $collectionItems = array(); $collectionBackend = self::getBackend('folder'); $sharedParents = $collectionBackend->getParents($item, $shareWith, $uidOwner); foreach ($sharedParents as $parent) { $collectionItems[] = $parent; } if ($limit === 1) { return reset($collectionItems); } return self::formatResult($collectionItems, $column, $backend, $format, $parameters); } return array(); }
/** * @brief Sharing a file or folder with a group * @param array $params The hook params */ public static function shareFileOrFolderWithGroup($params) { // User performing the share self::shareNotificationForSharer('shared_group_self', $params['shareWith'], $params['fileSource'], $params['itemType']); // Members of the new group $affectedUsers = array(); $usersInGroup = \OC_Group::usersInGroup($params['shareWith']); foreach ($usersInGroup as $user) { $affectedUsers[$user] = $params['fileTarget']; } // Remove the triggering user, we already managed his notifications unset($affectedUsers[\OCP\User::getUser()]); if (empty($affectedUsers)) { return; } $filteredStreamUsersInGroup = UserSettings::filterUsersBySetting($usersInGroup, 'stream', Data::TYPE_SHARED); $filteredEmailUsersInGroup = UserSettings::filterUsersBySetting($usersInGroup, 'email', Data::TYPE_SHARED); // Check when there was a naming conflict and the target is different // for some of the users $query = \OC_DB::prepare('SELECT `share_with`, `file_target` FROM `*PREFIX*share` WHERE `parent` = ? '); $result = $query->execute(array($params['id'])); if (\OCP\DB::isError($result)) { \OCP\Util::writeLog('OCA\\Activity\\Hooks::shareFileOrFolderWithGroup', \OC_DB::getErrorMessage($result), \OC_Log::ERROR); } else { while ($row = $result->fetchRow()) { $affectedUsers[$row['share_with']] = $row['file_target']; } } foreach ($affectedUsers as $user => $path) { if (empty($filteredStreamUsersInGroup[$user]) && empty($filteredEmailUsersInGroup[$user])) { continue; } self::addNotificationsForUser($user, 'shared_with_by', array($path, \OCP\User::getUser()), $path, $params['itemType'] === 'file', !empty($filteredStreamUsersInGroup[$user]), !empty($filteredEmailUsersInGroup[$user]) ? $filteredEmailUsersInGroup[$user] : 0); } }
/** * get owner of the shared files. * @param int $id ID of a share * @return string owner */ public function getOwnerFromSharedFile($id) { $query = \OCP\DB::prepare('SELECT `parent`, `uid_owner` FROM `*PREFIX*share` WHERE `id` = ?', 1); $result = $query->execute(array($id)); $source = null; if (\OCP\DB::isError($result)) { \OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); } else { $source = $result->fetchRow(); } $fileOwner = false; if ($source && isset($source['parent'])) { $parent = $source['parent']; while (isset($parent)) { $query = \OCP\DB::prepare('SELECT `parent`, `uid_owner` FROM `*PREFIX*share` WHERE `id` = ?', 1); $result = $query->execute(array($parent)); $item = null; if (\OCP\DB::isError($result)) { \OCP\Util::writeLog('Encryption library', \OC_DB::getErrorMessage($result), \OCP\Util::ERROR); } else { $item = $result->fetchRow(); } if ($item && isset($item['parent'])) { $parent = $item['parent']; } else { $fileOwner = $item['uid_owner']; break; } } } else { $fileOwner = $source['uid_owner']; } return $fileOwner; }
/** * counts the users in the database * * @return int|bool */ public function countUsers() { $query = \OC_DB::prepare('SELECT COUNT(*) FROM `*PREFIX*users`'); $result = $query->execute(); if ($result === false) { \OCP\Util::writeLog('core', \OC_DB::getErrorMessage(), \OCP\Util::ERROR); return false; } return $result->fetchOne(); }