| Conditions | 121 |
| Paths | > 20000 |
| Total Lines | 401 |
| Code Lines | 271 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 0 | ||
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.
There are several approaches to avoid long parameter lists:
| 1 | <?php |
||
| 475 | public static function getItems($itemType, $item = null, $shareType = null, $shareWith = null, |
||
| 476 | $uidOwner = null, $format = self::FORMAT_NONE, $parameters = null, $limit = -1, |
||
| 477 | $includeCollections = false, $itemShareWithBySource = false, $checkExpireDate = true) { |
||
| 478 | if (\OC::$server->getConfig()->getAppValue('core', 'shareapi_enabled', 'yes') != 'yes') { |
||
| 479 | return []; |
||
| 480 | } |
||
| 481 | $backend = self::getBackend($itemType); |
||
| 482 | $collectionTypes = false; |
||
| 483 | // Get filesystem root to add it to the file target and remove from the |
||
| 484 | // file source, match file_source with the file cache |
||
| 485 | if ($itemType == 'file' || $itemType == 'folder') { |
||
| 486 | if (!is_null($uidOwner)) { |
||
| 487 | $root = \OC\Files\Filesystem::getRoot(); |
||
| 488 | } else { |
||
| 489 | $root = ''; |
||
| 490 | } |
||
| 491 | $where = 'INNER JOIN `*PREFIX*filecache` ON `file_source` = `*PREFIX*filecache`.`fileid` '; |
||
| 492 | if (!isset($item)) { |
||
| 493 | $where .= ' AND `file_target` IS NOT NULL '; |
||
| 494 | } |
||
| 495 | $where .= 'INNER JOIN `*PREFIX*storages` ON `numeric_id` = `*PREFIX*filecache`.`storage` '; |
||
| 496 | $fileDependent = true; |
||
| 497 | $queryArgs = []; |
||
| 498 | } else { |
||
| 499 | $fileDependent = false; |
||
| 500 | $root = ''; |
||
| 501 | $collectionTypes = self::getCollectionItemTypes($itemType); |
||
| 502 | if ($includeCollections && !isset($item) && $collectionTypes) { |
||
| 503 | // If includeCollections is true, find collections of this item type, e.g. a music album contains songs |
||
| 504 | if (!in_array($itemType, $collectionTypes)) { |
||
| 505 | $itemTypes = array_merge([$itemType], $collectionTypes); |
||
| 506 | } else { |
||
| 507 | $itemTypes = $collectionTypes; |
||
| 508 | } |
||
| 509 | $placeholders = implode(',', array_fill(0, count($itemTypes), '?')); |
||
| 510 | $where = ' WHERE `item_type` IN ('.$placeholders.'))'; |
||
| 511 | $queryArgs = $itemTypes; |
||
| 512 | } else { |
||
| 513 | $where = ' WHERE `item_type` = ?'; |
||
| 514 | $queryArgs = [$itemType]; |
||
| 515 | } |
||
| 516 | } |
||
| 517 | if (\OC::$server->getConfig()->getAppValue('core', 'shareapi_allow_links', 'yes') !== 'yes') { |
||
| 518 | $where .= ' AND `share_type` != ?'; |
||
| 519 | $queryArgs[] = IShare::TYPE_LINK; |
||
| 520 | } |
||
| 521 | if (isset($shareType)) { |
||
| 522 | // Include all user and group items |
||
| 523 | if ($shareType == self::$shareTypeUserAndGroups && isset($shareWith)) { |
||
| 524 | $where .= ' AND ((`share_type` in (?, ?) AND `share_with` = ?) '; |
||
| 525 | $queryArgs[] = IShare::TYPE_USER; |
||
| 526 | $queryArgs[] = self::$shareTypeGroupUserUnique; |
||
| 527 | $queryArgs[] = $shareWith; |
||
| 528 | |||
| 529 | $user = \OC::$server->getUserManager()->get($shareWith); |
||
| 530 | $groups = []; |
||
| 531 | if ($user) { |
||
| 532 | $groups = \OC::$server->getGroupManager()->getUserGroupIds($user); |
||
| 533 | } |
||
| 534 | if (!empty($groups)) { |
||
| 535 | $placeholders = implode(',', array_fill(0, count($groups), '?')); |
||
| 536 | $where .= ' OR (`share_type` = ? AND `share_with` IN ('.$placeholders.')) '; |
||
| 537 | $queryArgs[] = IShare::TYPE_GROUP; |
||
| 538 | $queryArgs = array_merge($queryArgs, $groups); |
||
| 539 | } |
||
| 540 | $where .= ')'; |
||
| 541 | // Don't include own group shares |
||
| 542 | $where .= ' AND `uid_owner` != ?'; |
||
| 543 | $queryArgs[] = $shareWith; |
||
| 544 | } else { |
||
| 545 | $where .= ' AND `share_type` = ?'; |
||
| 546 | $queryArgs[] = $shareType; |
||
| 547 | if (isset($shareWith)) { |
||
| 548 | $where .= ' AND `share_with` = ?'; |
||
| 549 | $queryArgs[] = $shareWith; |
||
| 550 | } |
||
| 551 | } |
||
| 552 | } |
||
| 553 | if (isset($uidOwner)) { |
||
| 554 | $where .= ' AND `uid_owner` = ?'; |
||
| 555 | $queryArgs[] = $uidOwner; |
||
| 556 | if (!isset($shareType)) { |
||
| 557 | // Prevent unique user targets for group shares from being selected |
||
| 558 | $where .= ' AND `share_type` != ?'; |
||
| 559 | $queryArgs[] = self::$shareTypeGroupUserUnique; |
||
| 560 | } |
||
| 561 | if ($fileDependent) { |
||
| 562 | $column = 'file_source'; |
||
| 563 | } else { |
||
| 564 | $column = 'item_source'; |
||
| 565 | } |
||
| 566 | } else { |
||
| 567 | if ($fileDependent) { |
||
| 568 | $column = 'file_target'; |
||
| 569 | } else { |
||
| 570 | $column = 'item_target'; |
||
| 571 | } |
||
| 572 | } |
||
| 573 | if (isset($item)) { |
||
| 574 | $collectionTypes = self::getCollectionItemTypes($itemType); |
||
| 575 | if ($includeCollections && $collectionTypes && !in_array('folder', $collectionTypes)) { |
||
| 576 | $where .= ' AND ('; |
||
| 577 | } else { |
||
| 578 | $where .= ' AND'; |
||
| 579 | } |
||
| 580 | // If looking for own shared items, check item_source else check item_target |
||
| 581 | if (isset($uidOwner) || $itemShareWithBySource) { |
||
| 582 | // If item type is a file, file source needs to be checked in case the item was converted |
||
| 583 | if ($fileDependent) { |
||
| 584 | $where .= ' `file_source` = ?'; |
||
| 585 | $column = 'file_source'; |
||
| 586 | } else { |
||
| 587 | $where .= ' `item_source` = ?'; |
||
| 588 | $column = 'item_source'; |
||
| 589 | } |
||
| 590 | } else { |
||
| 591 | if ($fileDependent) { |
||
| 592 | $where .= ' `file_target` = ?'; |
||
| 593 | $item = \OC\Files\Filesystem::normalizePath($item); |
||
| 594 | } else { |
||
| 595 | $where .= ' `item_target` = ?'; |
||
| 596 | } |
||
| 597 | } |
||
| 598 | $queryArgs[] = $item; |
||
| 599 | if ($includeCollections && $collectionTypes && !in_array('folder', $collectionTypes)) { |
||
| 600 | $placeholders = implode(',', array_fill(0, count($collectionTypes), '?')); |
||
| 601 | $where .= ' OR `item_type` IN ('.$placeholders.'))'; |
||
| 602 | $queryArgs = array_merge($queryArgs, $collectionTypes); |
||
| 603 | } |
||
| 604 | } |
||
| 605 | |||
| 606 | if ($shareType == self::$shareTypeUserAndGroups && $limit === 1) { |
||
| 607 | // Make sure the unique user target is returned if it exists, |
||
| 608 | // unique targets should follow the group share in the database |
||
| 609 | // If the limit is not 1, the filtering can be done later |
||
| 610 | $where .= ' ORDER BY `*PREFIX*share`.`id` DESC'; |
||
| 611 | } else { |
||
| 612 | $where .= ' ORDER BY `*PREFIX*share`.`id` ASC'; |
||
| 613 | } |
||
| 614 | |||
| 615 | if ($limit != -1 && !$includeCollections) { |
||
| 616 | // The limit must be at least 3, because filtering needs to be done |
||
| 617 | if ($limit < 3) { |
||
| 618 | $queryLimit = 3; |
||
| 619 | } else { |
||
| 620 | $queryLimit = $limit; |
||
| 621 | } |
||
| 622 | } else { |
||
| 623 | $queryLimit = null; |
||
| 624 | } |
||
| 625 | $select = self::createSelectStatement($format, $fileDependent, $uidOwner); |
||
| 626 | $root = strlen($root); |
||
| 627 | $query = \OC_DB::prepare('SELECT '.$select.' FROM `*PREFIX*share` '.$where, $queryLimit); |
||
| 628 | $result = $query->execute($queryArgs); |
||
| 629 | if ($result === false) { |
||
| 630 | \OCP\Util::writeLog('OCP\Share', |
||
| 631 | \OC_DB::getErrorMessage() . ', select=' . $select . ' where=', |
||
| 632 | ILogger::ERROR); |
||
| 633 | } |
||
| 634 | $items = []; |
||
| 635 | $targets = []; |
||
| 636 | $switchedItems = []; |
||
| 637 | $mounts = []; |
||
| 638 | while ($row = $result->fetchRow()) { |
||
| 639 | self::transformDBResults($row); |
||
| 640 | // Filter out duplicate group shares for users with unique targets |
||
| 641 | if ($fileDependent && !self::isFileReachable($row['path'], $row['storage_id'])) { |
||
| 642 | continue; |
||
| 643 | } |
||
| 644 | if ($row['share_type'] == self::$shareTypeGroupUserUnique && isset($items[$row['parent']])) { |
||
| 645 | $row['share_type'] = IShare::TYPE_GROUP; |
||
| 646 | $row['unique_name'] = true; // remember that we use a unique name for this user |
||
| 647 | $row['share_with'] = $items[$row['parent']]['share_with']; |
||
| 648 | // if the group share was unshared from the user we keep the permission, otherwise |
||
| 649 | // we take the permission from the parent because this is always the up-to-date |
||
| 650 | // permission for the group share |
||
| 651 | if ($row['permissions'] > 0) { |
||
| 652 | $row['permissions'] = $items[$row['parent']]['permissions']; |
||
| 653 | } |
||
| 654 | // Remove the parent group share |
||
| 655 | unset($items[$row['parent']]); |
||
| 656 | if ($row['permissions'] == 0) { |
||
| 657 | continue; |
||
| 658 | } |
||
| 659 | } elseif (!isset($uidOwner)) { |
||
| 660 | // Check if the same target already exists |
||
| 661 | if (isset($targets[$row['id']])) { |
||
| 662 | // Check if the same owner shared with the user twice |
||
| 663 | // through a group and user share - this is allowed |
||
| 664 | $id = $targets[$row['id']]; |
||
| 665 | if (isset($items[$id]) && $items[$id]['uid_owner'] == $row['uid_owner']) { |
||
| 666 | // Switch to group share type to ensure resharing conditions aren't bypassed |
||
| 667 | if ($items[$id]['share_type'] != IShare::TYPE_GROUP) { |
||
| 668 | $items[$id]['share_type'] = IShare::TYPE_GROUP; |
||
| 669 | $items[$id]['share_with'] = $row['share_with']; |
||
| 670 | } |
||
| 671 | // Switch ids if sharing permission is granted on only |
||
| 672 | // one share to ensure correct parent is used if resharing |
||
| 673 | if (~(int)$items[$id]['permissions'] & \OCP\Constants::PERMISSION_SHARE |
||
| 674 | && (int)$row['permissions'] & \OCP\Constants::PERMISSION_SHARE) { |
||
| 675 | $items[$row['id']] = $items[$id]; |
||
| 676 | $switchedItems[$id] = $row['id']; |
||
| 677 | unset($items[$id]); |
||
| 678 | $id = $row['id']; |
||
| 679 | } |
||
| 680 | $items[$id]['permissions'] |= (int)$row['permissions']; |
||
| 681 | } |
||
| 682 | continue; |
||
| 683 | } elseif (!empty($row['parent'])) { |
||
| 684 | $targets[$row['parent']] = $row['id']; |
||
| 685 | } |
||
| 686 | } |
||
| 687 | // Remove root from file source paths if retrieving own shared items |
||
| 688 | if (isset($uidOwner) && isset($row['path'])) { |
||
| 689 | if (isset($row['parent'])) { |
||
| 690 | $query = \OC_DB::prepare('SELECT `file_target` FROM `*PREFIX*share` WHERE `id` = ?'); |
||
| 691 | $parentResult = $query->execute([$row['parent']]); |
||
| 692 | if ($result === false) { |
||
| 693 | \OCP\Util::writeLog('OCP\Share', 'Can\'t select parent: ' . |
||
| 694 | \OC_DB::getErrorMessage() . ', select=' . $select . ' where=' . $where, |
||
| 695 | ILogger::ERROR); |
||
| 696 | } else { |
||
| 697 | $parentRow = $parentResult->fetchRow(); |
||
| 698 | $tmpPath = $parentRow['file_target']; |
||
| 699 | // find the right position where the row path continues from the target path |
||
| 700 | $pos = strrpos($row['path'], $parentRow['file_target']); |
||
| 701 | $subPath = substr($row['path'], $pos); |
||
| 702 | $splitPath = explode('/', $subPath); |
||
| 703 | foreach (array_slice($splitPath, 2) as $pathPart) { |
||
| 704 | $tmpPath = $tmpPath . '/' . $pathPart; |
||
| 705 | } |
||
| 706 | $row['path'] = $tmpPath; |
||
| 707 | } |
||
| 708 | } else { |
||
| 709 | if (!isset($mounts[$row['storage']])) { |
||
| 710 | $mountPoints = \OC\Files\Filesystem::getMountByNumericId($row['storage']); |
||
| 711 | if (is_array($mountPoints) && !empty($mountPoints)) { |
||
| 712 | $mounts[$row['storage']] = current($mountPoints); |
||
| 713 | } |
||
| 714 | } |
||
| 715 | if (!empty($mounts[$row['storage']])) { |
||
| 716 | $path = $mounts[$row['storage']]->getMountPoint().$row['path']; |
||
| 717 | $relPath = substr($path, $root); // path relative to data/user |
||
| 718 | $row['path'] = rtrim($relPath, '/'); |
||
| 719 | } |
||
| 720 | } |
||
| 721 | } |
||
| 722 | |||
| 723 | if ($checkExpireDate) { |
||
| 724 | if (self::expireItem($row)) { |
||
| 725 | continue; |
||
| 726 | } |
||
| 727 | } |
||
| 728 | // Check if resharing is allowed, if not remove share permission |
||
| 729 | if (isset($row['permissions']) && (!self::isResharingAllowed() | \OCP\Util::isSharingDisabledForUser())) { |
||
| 730 | $row['permissions'] &= ~\OCP\Constants::PERMISSION_SHARE; |
||
| 731 | } |
||
| 732 | // Add display names to result |
||
| 733 | $row['share_with_displayname'] = $row['share_with']; |
||
| 734 | if (isset($row['share_with']) && $row['share_with'] != '' && |
||
| 735 | $row['share_type'] === IShare::TYPE_USER) { |
||
| 736 | $shareWithUser = \OC::$server->getUserManager()->get($row['share_with']); |
||
| 737 | $row['share_with_displayname'] = $shareWithUser === null ? $row['share_with'] : $shareWithUser->getDisplayName(); |
||
| 738 | } elseif (isset($row['share_with']) && $row['share_with'] != '' && |
||
| 739 | $row['share_type'] === IShare::TYPE_REMOTE) { |
||
| 740 | $addressBookEntries = \OC::$server->getContactsManager()->search($row['share_with'], ['CLOUD']); |
||
| 741 | foreach ($addressBookEntries as $entry) { |
||
| 742 | foreach ($entry['CLOUD'] as $cloudID) { |
||
| 743 | if ($cloudID === $row['share_with']) { |
||
| 744 | $row['share_with_displayname'] = $entry['FN']; |
||
| 745 | } |
||
| 746 | } |
||
| 747 | } |
||
| 748 | } |
||
| 749 | if (isset($row['uid_owner']) && $row['uid_owner'] != '') { |
||
| 750 | $ownerUser = \OC::$server->getUserManager()->get($row['uid_owner']); |
||
| 751 | $row['displayname_owner'] = $ownerUser === null ? $row['uid_owner'] : $ownerUser->getDisplayName(); |
||
| 752 | } |
||
| 753 | |||
| 754 | if ($row['permissions'] > 0) { |
||
| 755 | $items[$row['id']] = $row; |
||
| 756 | } |
||
| 757 | } |
||
| 758 | |||
| 759 | // group items if we are looking for items shared with the current user |
||
| 760 | if (isset($shareWith) && $shareWith === \OCP\User::getUser()) { |
||
| 761 | $items = self::groupItems($items, $itemType); |
||
| 762 | } |
||
| 763 | |||
| 764 | if (!empty($items)) { |
||
| 765 | $collectionItems = []; |
||
| 766 | foreach ($items as &$row) { |
||
| 767 | // Return only the item instead of a 2-dimensional array |
||
| 768 | if ($limit == 1 && $row[$column] == $item && ($row['item_type'] == $itemType || $itemType == 'file')) { |
||
| 769 | if ($format == self::FORMAT_NONE) { |
||
| 770 | return $row; |
||
| 771 | } else { |
||
| 772 | break; |
||
| 773 | } |
||
| 774 | } |
||
| 775 | // Check if this is a collection of the requested item type |
||
| 776 | if ($includeCollections && $collectionTypes && $row['item_type'] !== 'folder' && in_array($row['item_type'], $collectionTypes)) { |
||
| 777 | if (($collectionBackend = self::getBackend($row['item_type'])) |
||
| 778 | && $collectionBackend instanceof \OCP\Share_Backend_Collection) { |
||
| 779 | // Collections can be inside collections, check if the item is a collection |
||
| 780 | if (isset($item) && $row['item_type'] == $itemType && $row[$column] == $item) { |
||
| 781 | $collectionItems[] = $row; |
||
| 782 | } else { |
||
| 783 | $collection = []; |
||
| 784 | $collection['item_type'] = $row['item_type']; |
||
| 785 | if ($row['item_type'] == 'file' || $row['item_type'] == 'folder') { |
||
| 786 | $collection['path'] = basename($row['path']); |
||
| 787 | } |
||
| 788 | $row['collection'] = $collection; |
||
| 789 | // Fetch all of the children sources |
||
| 790 | $children = $collectionBackend->getChildren($row[$column]); |
||
| 791 | foreach ($children as $child) { |
||
| 792 | $childItem = $row; |
||
| 793 | $childItem['item_type'] = $itemType; |
||
| 794 | if ($row['item_type'] != 'file' && $row['item_type'] != 'folder') { |
||
| 795 | $childItem['item_source'] = $child['source']; |
||
| 796 | $childItem['item_target'] = $child['target']; |
||
| 797 | } |
||
| 798 | if ($backend instanceof \OCP\Share_Backend_File_Dependent) { |
||
| 799 | if ($row['item_type'] == 'file' || $row['item_type'] == 'folder') { |
||
| 800 | $childItem['file_source'] = $child['source']; |
||
| 801 | } else { // TODO is this really needed if we already know that we use the file backend? |
||
| 802 | $meta = \OC\Files\Filesystem::getFileInfo($child['file_path']); |
||
| 803 | $childItem['file_source'] = $meta['fileid']; |
||
| 804 | } |
||
| 805 | $childItem['file_target'] = |
||
| 806 | \OC\Files\Filesystem::normalizePath($child['file_path']); |
||
| 807 | } |
||
| 808 | if (isset($item)) { |
||
| 809 | if ($childItem[$column] == $item) { |
||
| 810 | // Return only the item instead of a 2-dimensional array |
||
| 811 | if ($limit == 1) { |
||
| 812 | if ($format == self::FORMAT_NONE) { |
||
| 813 | return $childItem; |
||
| 814 | } else { |
||
| 815 | // Unset the items array and break out of both loops |
||
| 816 | $items = []; |
||
| 817 | $items[] = $childItem; |
||
| 818 | break 2; |
||
| 819 | } |
||
| 820 | } else { |
||
| 821 | $collectionItems[] = $childItem; |
||
| 822 | } |
||
| 823 | } |
||
| 824 | } else { |
||
| 825 | $collectionItems[] = $childItem; |
||
| 826 | } |
||
| 827 | } |
||
| 828 | } |
||
| 829 | } |
||
| 830 | // Remove collection item |
||
| 831 | $toRemove = $row['id']; |
||
| 832 | if (array_key_exists($toRemove, $switchedItems)) { |
||
| 833 | $toRemove = $switchedItems[$toRemove]; |
||
| 834 | } |
||
| 835 | unset($items[$toRemove]); |
||
| 836 | } elseif ($includeCollections && $collectionTypes && in_array($row['item_type'], $collectionTypes)) { |
||
| 837 | // FIXME: Thats a dirty hack to improve file sharing performance, |
||
| 838 | // see github issue #10588 for more details |
||
| 839 | // Need to find a solution which works for all back-ends |
||
| 840 | $collectionBackend = self::getBackend($row['item_type']); |
||
| 841 | $sharedParents = $collectionBackend->getParents($row['item_source']); |
||
| 842 | foreach ($sharedParents as $parent) { |
||
| 843 | $collectionItems[] = $parent; |
||
| 844 | } |
||
| 845 | } |
||
| 846 | } |
||
| 847 | if (!empty($collectionItems)) { |
||
| 848 | $collectionItems = array_unique($collectionItems, SORT_REGULAR); |
||
| 849 | $items = array_merge($items, $collectionItems); |
||
| 850 | } |
||
| 851 | |||
| 852 | // filter out invalid items, these can appear when subshare entries exist |
||
| 853 | // for a group in which the requested user isn't a member any more |
||
| 854 | $items = array_filter($items, function ($item) { |
||
| 855 | return $item['share_type'] !== self::$shareTypeGroupUserUnique; |
||
| 856 | }); |
||
| 857 | |||
| 858 | return self::formatResult($items, $column, $backend, $format, $parameters); |
||
| 859 | } elseif ($includeCollections && $collectionTypes && in_array('folder', $collectionTypes)) { |
||
| 860 | // FIXME: Thats a dirty hack to improve file sharing performance, |
||
| 861 | // see github issue #10588 for more details |
||
| 862 | // Need to find a solution which works for all back-ends |
||
| 863 | $collectionItems = []; |
||
| 864 | $collectionBackend = self::getBackend('folder'); |
||
| 865 | $sharedParents = $collectionBackend->getParents($item, $shareWith, $uidOwner); |
||
| 866 | foreach ($sharedParents as $parent) { |
||
| 867 | $collectionItems[] = $parent; |
||
| 868 | } |
||
| 869 | if ($limit === 1) { |
||
| 870 | return reset($collectionItems); |
||
| 871 | } |
||
| 872 | return self::formatResult($collectionItems, $column, $backend, $format, $parameters); |
||
| 873 | } |
||
| 874 | |||
| 875 | return []; |
||
| 876 | } |
||
| 1144 |
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.