1*a1a3b679SAndreas Boehler<?php 2*a1a3b679SAndreas Boehler 3*a1a3b679SAndreas Boehlernamespace Sabre\DAVACL; 4*a1a3b679SAndreas Boehler 5*a1a3b679SAndreas Boehleruse Sabre\DAV; 6*a1a3b679SAndreas Boehleruse Sabre\HTTP\URLUtil; 7*a1a3b679SAndreas Boehler 8*a1a3b679SAndreas Boehler/** 9*a1a3b679SAndreas Boehler * Principals Collection 10*a1a3b679SAndreas Boehler * 11*a1a3b679SAndreas Boehler * This is a helper class that easily allows you to create a collection that 12*a1a3b679SAndreas Boehler * has a childnode for every principal. 13*a1a3b679SAndreas Boehler * 14*a1a3b679SAndreas Boehler * To use this class, simply implement the getChildForPrincipal method. 15*a1a3b679SAndreas Boehler * 16*a1a3b679SAndreas Boehler * @copyright Copyright (C) 2007-2015 fruux GmbH (https://fruux.com/). 17*a1a3b679SAndreas Boehler * @author Evert Pot (http://evertpot.com/) 18*a1a3b679SAndreas Boehler * @license http://sabre.io/license/ Modified BSD License 19*a1a3b679SAndreas Boehler */ 20*a1a3b679SAndreas Boehlerabstract class AbstractPrincipalCollection extends DAV\Collection implements IPrincipalCollection { 21*a1a3b679SAndreas Boehler 22*a1a3b679SAndreas Boehler /** 23*a1a3b679SAndreas Boehler * Principal backend 24*a1a3b679SAndreas Boehler * 25*a1a3b679SAndreas Boehler * @var PrincipalBackend\BackendInterface 26*a1a3b679SAndreas Boehler */ 27*a1a3b679SAndreas Boehler protected $principalBackend; 28*a1a3b679SAndreas Boehler 29*a1a3b679SAndreas Boehler /** 30*a1a3b679SAndreas Boehler * The path to the principals we're listing from. 31*a1a3b679SAndreas Boehler * 32*a1a3b679SAndreas Boehler * @var string 33*a1a3b679SAndreas Boehler */ 34*a1a3b679SAndreas Boehler protected $principalPrefix; 35*a1a3b679SAndreas Boehler 36*a1a3b679SAndreas Boehler /** 37*a1a3b679SAndreas Boehler * If this value is set to true, it effectively disables listing of users 38*a1a3b679SAndreas Boehler * it still allows user to find other users if they have an exact url. 39*a1a3b679SAndreas Boehler * 40*a1a3b679SAndreas Boehler * @var bool 41*a1a3b679SAndreas Boehler */ 42*a1a3b679SAndreas Boehler public $disableListing = false; 43*a1a3b679SAndreas Boehler 44*a1a3b679SAndreas Boehler /** 45*a1a3b679SAndreas Boehler * Creates the object 46*a1a3b679SAndreas Boehler * 47*a1a3b679SAndreas Boehler * This object must be passed the principal backend. This object will 48*a1a3b679SAndreas Boehler * filter all principals from a specified prefix ($principalPrefix). The 49*a1a3b679SAndreas Boehler * default is 'principals', if your principals are stored in a different 50*a1a3b679SAndreas Boehler * collection, override $principalPrefix 51*a1a3b679SAndreas Boehler * 52*a1a3b679SAndreas Boehler * 53*a1a3b679SAndreas Boehler * @param PrincipalBackend\BackendInterface $principalBackend 54*a1a3b679SAndreas Boehler * @param string $principalPrefix 55*a1a3b679SAndreas Boehler */ 56*a1a3b679SAndreas Boehler function __construct(PrincipalBackend\BackendInterface $principalBackend, $principalPrefix = 'principals') { 57*a1a3b679SAndreas Boehler 58*a1a3b679SAndreas Boehler $this->principalPrefix = $principalPrefix; 59*a1a3b679SAndreas Boehler $this->principalBackend = $principalBackend; 60*a1a3b679SAndreas Boehler 61*a1a3b679SAndreas Boehler } 62*a1a3b679SAndreas Boehler 63*a1a3b679SAndreas Boehler /** 64*a1a3b679SAndreas Boehler * This method returns a node for a principal. 65*a1a3b679SAndreas Boehler * 66*a1a3b679SAndreas Boehler * The passed array contains principal information, and is guaranteed to 67*a1a3b679SAndreas Boehler * at least contain a uri item. Other properties may or may not be 68*a1a3b679SAndreas Boehler * supplied by the authentication backend. 69*a1a3b679SAndreas Boehler * 70*a1a3b679SAndreas Boehler * @param array $principalInfo 71*a1a3b679SAndreas Boehler * @return IPrincipal 72*a1a3b679SAndreas Boehler */ 73*a1a3b679SAndreas Boehler abstract function getChildForPrincipal(array $principalInfo); 74*a1a3b679SAndreas Boehler 75*a1a3b679SAndreas Boehler /** 76*a1a3b679SAndreas Boehler * Returns the name of this collection. 77*a1a3b679SAndreas Boehler * 78*a1a3b679SAndreas Boehler * @return string 79*a1a3b679SAndreas Boehler */ 80*a1a3b679SAndreas Boehler function getName() { 81*a1a3b679SAndreas Boehler 82*a1a3b679SAndreas Boehler list(, $name) = URLUtil::splitPath($this->principalPrefix); 83*a1a3b679SAndreas Boehler return $name; 84*a1a3b679SAndreas Boehler 85*a1a3b679SAndreas Boehler } 86*a1a3b679SAndreas Boehler 87*a1a3b679SAndreas Boehler /** 88*a1a3b679SAndreas Boehler * Return the list of users 89*a1a3b679SAndreas Boehler * 90*a1a3b679SAndreas Boehler * @return array 91*a1a3b679SAndreas Boehler */ 92*a1a3b679SAndreas Boehler function getChildren() { 93*a1a3b679SAndreas Boehler 94*a1a3b679SAndreas Boehler if ($this->disableListing) 95*a1a3b679SAndreas Boehler throw new DAV\Exception\MethodNotAllowed('Listing members of this collection is disabled'); 96*a1a3b679SAndreas Boehler 97*a1a3b679SAndreas Boehler $children = []; 98*a1a3b679SAndreas Boehler foreach ($this->principalBackend->getPrincipalsByPrefix($this->principalPrefix) as $principalInfo) { 99*a1a3b679SAndreas Boehler 100*a1a3b679SAndreas Boehler $children[] = $this->getChildForPrincipal($principalInfo); 101*a1a3b679SAndreas Boehler 102*a1a3b679SAndreas Boehler 103*a1a3b679SAndreas Boehler } 104*a1a3b679SAndreas Boehler return $children; 105*a1a3b679SAndreas Boehler 106*a1a3b679SAndreas Boehler } 107*a1a3b679SAndreas Boehler 108*a1a3b679SAndreas Boehler /** 109*a1a3b679SAndreas Boehler * Returns a child object, by its name. 110*a1a3b679SAndreas Boehler * 111*a1a3b679SAndreas Boehler * @param string $name 112*a1a3b679SAndreas Boehler * @throws DAV\Exception\NotFound 113*a1a3b679SAndreas Boehler * @return IPrincipal 114*a1a3b679SAndreas Boehler */ 115*a1a3b679SAndreas Boehler function getChild($name) { 116*a1a3b679SAndreas Boehler 117*a1a3b679SAndreas Boehler $principalInfo = $this->principalBackend->getPrincipalByPath($this->principalPrefix . '/' . $name); 118*a1a3b679SAndreas Boehler if (!$principalInfo) throw new DAV\Exception\NotFound('Principal with name ' . $name . ' not found'); 119*a1a3b679SAndreas Boehler return $this->getChildForPrincipal($principalInfo); 120*a1a3b679SAndreas Boehler 121*a1a3b679SAndreas Boehler } 122*a1a3b679SAndreas Boehler 123*a1a3b679SAndreas Boehler /** 124*a1a3b679SAndreas Boehler * This method is used to search for principals matching a set of 125*a1a3b679SAndreas Boehler * properties. 126*a1a3b679SAndreas Boehler * 127*a1a3b679SAndreas Boehler * This search is specifically used by RFC3744's principal-property-search 128*a1a3b679SAndreas Boehler * REPORT. You should at least allow searching on 129*a1a3b679SAndreas Boehler * http://sabredav.org/ns}email-address. 130*a1a3b679SAndreas Boehler * 131*a1a3b679SAndreas Boehler * The actual search should be a unicode-non-case-sensitive search. The 132*a1a3b679SAndreas Boehler * keys in searchProperties are the WebDAV property names, while the values 133*a1a3b679SAndreas Boehler * are the property values to search on. 134*a1a3b679SAndreas Boehler * 135*a1a3b679SAndreas Boehler * By default, if multiple properties are submitted to this method, the 136*a1a3b679SAndreas Boehler * various properties should be combined with 'AND'. If $test is set to 137*a1a3b679SAndreas Boehler * 'anyof', it should be combined using 'OR'. 138*a1a3b679SAndreas Boehler * 139*a1a3b679SAndreas Boehler * This method should simply return a list of 'child names', which may be 140*a1a3b679SAndreas Boehler * used to call $this->getChild in the future. 141*a1a3b679SAndreas Boehler * 142*a1a3b679SAndreas Boehler * @param array $searchProperties 143*a1a3b679SAndreas Boehler * @param string $test 144*a1a3b679SAndreas Boehler * @return array 145*a1a3b679SAndreas Boehler */ 146*a1a3b679SAndreas Boehler function searchPrincipals(array $searchProperties, $test = 'allof') { 147*a1a3b679SAndreas Boehler 148*a1a3b679SAndreas Boehler $result = $this->principalBackend->searchPrincipals($this->principalPrefix, $searchProperties, $test); 149*a1a3b679SAndreas Boehler $r = []; 150*a1a3b679SAndreas Boehler 151*a1a3b679SAndreas Boehler foreach ($result as $row) { 152*a1a3b679SAndreas Boehler list(, $r[]) = URLUtil::splitPath($row); 153*a1a3b679SAndreas Boehler } 154*a1a3b679SAndreas Boehler 155*a1a3b679SAndreas Boehler return $r; 156*a1a3b679SAndreas Boehler 157*a1a3b679SAndreas Boehler } 158*a1a3b679SAndreas Boehler 159*a1a3b679SAndreas Boehler /** 160*a1a3b679SAndreas Boehler * Finds a principal by its URI. 161*a1a3b679SAndreas Boehler * 162*a1a3b679SAndreas Boehler * This method may receive any type of uri, but mailto: addresses will be 163*a1a3b679SAndreas Boehler * the most common. 164*a1a3b679SAndreas Boehler * 165*a1a3b679SAndreas Boehler * Implementation of this API is optional. It is currently used by the 166*a1a3b679SAndreas Boehler * CalDAV system to find principals based on their email addresses. If this 167*a1a3b679SAndreas Boehler * API is not implemented, some features may not work correctly. 168*a1a3b679SAndreas Boehler * 169*a1a3b679SAndreas Boehler * This method must return a relative principal path, or null, if the 170*a1a3b679SAndreas Boehler * principal was not found or you refuse to find it. 171*a1a3b679SAndreas Boehler * 172*a1a3b679SAndreas Boehler * @param string $uri 173*a1a3b679SAndreas Boehler * @return string 174*a1a3b679SAndreas Boehler */ 175*a1a3b679SAndreas Boehler function findByUri($uri) { 176*a1a3b679SAndreas Boehler 177*a1a3b679SAndreas Boehler return $this->principalBackend->findByUri($uri, $this->principalPrefix); 178*a1a3b679SAndreas Boehler 179*a1a3b679SAndreas Boehler } 180*a1a3b679SAndreas Boehler 181*a1a3b679SAndreas Boehler} 182