xref: /plugin/davcal/vendor/sabre/dav/lib/DAVACL/PrincipalBackend/PDO.php (revision a1a3b6794e0e143a4a8b51d3185ce2d339be61ab)
1*a1a3b679SAndreas Boehler<?php
2*a1a3b679SAndreas Boehler
3*a1a3b679SAndreas Boehlernamespace Sabre\DAVACL\PrincipalBackend;
4*a1a3b679SAndreas Boehler
5*a1a3b679SAndreas Boehleruse Sabre\DAV;
6*a1a3b679SAndreas Boehleruse Sabre\DAV\MkCol;
7*a1a3b679SAndreas Boehleruse Sabre\HTTP\URLUtil;
8*a1a3b679SAndreas Boehler
9*a1a3b679SAndreas Boehler/**
10*a1a3b679SAndreas Boehler * PDO principal backend
11*a1a3b679SAndreas Boehler *
12*a1a3b679SAndreas Boehler *
13*a1a3b679SAndreas Boehler * This backend assumes all principals are in a single collection. The default collection
14*a1a3b679SAndreas Boehler * is 'principals/', but this can be overriden.
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 Boehlerclass PDO extends AbstractBackend implements CreatePrincipalSupport {
21*a1a3b679SAndreas Boehler
22*a1a3b679SAndreas Boehler    /**
23*a1a3b679SAndreas Boehler     * PDO table name for 'principals'
24*a1a3b679SAndreas Boehler     *
25*a1a3b679SAndreas Boehler     * @var string
26*a1a3b679SAndreas Boehler     */
27*a1a3b679SAndreas Boehler    public $tableName = 'principals';
28*a1a3b679SAndreas Boehler
29*a1a3b679SAndreas Boehler    /**
30*a1a3b679SAndreas Boehler     * PDO table name for 'group members'
31*a1a3b679SAndreas Boehler     *
32*a1a3b679SAndreas Boehler     * @var string
33*a1a3b679SAndreas Boehler     */
34*a1a3b679SAndreas Boehler    public $groupMembersTableName = 'groupmembers';
35*a1a3b679SAndreas Boehler
36*a1a3b679SAndreas Boehler    /**
37*a1a3b679SAndreas Boehler     * pdo
38*a1a3b679SAndreas Boehler     *
39*a1a3b679SAndreas Boehler     * @var PDO
40*a1a3b679SAndreas Boehler     */
41*a1a3b679SAndreas Boehler    protected $pdo;
42*a1a3b679SAndreas Boehler
43*a1a3b679SAndreas Boehler    /**
44*a1a3b679SAndreas Boehler     * A list of additional fields to support
45*a1a3b679SAndreas Boehler     *
46*a1a3b679SAndreas Boehler     * @var array
47*a1a3b679SAndreas Boehler     */
48*a1a3b679SAndreas Boehler    protected $fieldMap = [
49*a1a3b679SAndreas Boehler
50*a1a3b679SAndreas Boehler        /**
51*a1a3b679SAndreas Boehler         * This property can be used to display the users' real name.
52*a1a3b679SAndreas Boehler         */
53*a1a3b679SAndreas Boehler        '{DAV:}displayname' => [
54*a1a3b679SAndreas Boehler            'dbField' => 'displayname',
55*a1a3b679SAndreas Boehler        ],
56*a1a3b679SAndreas Boehler
57*a1a3b679SAndreas Boehler        /**
58*a1a3b679SAndreas Boehler         * This is the users' primary email-address.
59*a1a3b679SAndreas Boehler         */
60*a1a3b679SAndreas Boehler        '{http://sabredav.org/ns}email-address' => [
61*a1a3b679SAndreas Boehler            'dbField' => 'email',
62*a1a3b679SAndreas Boehler        ],
63*a1a3b679SAndreas Boehler    ];
64*a1a3b679SAndreas Boehler
65*a1a3b679SAndreas Boehler    /**
66*a1a3b679SAndreas Boehler     * Sets up the backend.
67*a1a3b679SAndreas Boehler     *
68*a1a3b679SAndreas Boehler     * @param PDO $pdo
69*a1a3b679SAndreas Boehler     */
70*a1a3b679SAndreas Boehler    function __construct(\PDO $pdo) {
71*a1a3b679SAndreas Boehler
72*a1a3b679SAndreas Boehler        $this->pdo = $pdo;
73*a1a3b679SAndreas Boehler
74*a1a3b679SAndreas Boehler    }
75*a1a3b679SAndreas Boehler
76*a1a3b679SAndreas Boehler    /**
77*a1a3b679SAndreas Boehler     * Returns a list of principals based on a prefix.
78*a1a3b679SAndreas Boehler     *
79*a1a3b679SAndreas Boehler     * This prefix will often contain something like 'principals'. You are only
80*a1a3b679SAndreas Boehler     * expected to return principals that are in this base path.
81*a1a3b679SAndreas Boehler     *
82*a1a3b679SAndreas Boehler     * You are expected to return at least a 'uri' for every user, you can
83*a1a3b679SAndreas Boehler     * return any additional properties if you wish so. Common properties are:
84*a1a3b679SAndreas Boehler     *   {DAV:}displayname
85*a1a3b679SAndreas Boehler     *   {http://sabredav.org/ns}email-address - This is a custom SabreDAV
86*a1a3b679SAndreas Boehler     *     field that's actualy injected in a number of other properties. If
87*a1a3b679SAndreas Boehler     *     you have an email address, use this property.
88*a1a3b679SAndreas Boehler     *
89*a1a3b679SAndreas Boehler     * @param string $prefixPath
90*a1a3b679SAndreas Boehler     * @return array
91*a1a3b679SAndreas Boehler     */
92*a1a3b679SAndreas Boehler    function getPrincipalsByPrefix($prefixPath) {
93*a1a3b679SAndreas Boehler
94*a1a3b679SAndreas Boehler        $fields = [
95*a1a3b679SAndreas Boehler            'uri',
96*a1a3b679SAndreas Boehler        ];
97*a1a3b679SAndreas Boehler
98*a1a3b679SAndreas Boehler        foreach ($this->fieldMap as $key => $value) {
99*a1a3b679SAndreas Boehler            $fields[] = $value['dbField'];
100*a1a3b679SAndreas Boehler        }
101*a1a3b679SAndreas Boehler        $result = $this->pdo->query('SELECT ' . implode(',', $fields) . '  FROM ' . $this->tableName);
102*a1a3b679SAndreas Boehler
103*a1a3b679SAndreas Boehler        $principals = [];
104*a1a3b679SAndreas Boehler
105*a1a3b679SAndreas Boehler        while ($row = $result->fetch(\PDO::FETCH_ASSOC)) {
106*a1a3b679SAndreas Boehler
107*a1a3b679SAndreas Boehler            // Checking if the principal is in the prefix
108*a1a3b679SAndreas Boehler            list($rowPrefix) = URLUtil::splitPath($row['uri']);
109*a1a3b679SAndreas Boehler            if ($rowPrefix !== $prefixPath) continue;
110*a1a3b679SAndreas Boehler
111*a1a3b679SAndreas Boehler            $principal = [
112*a1a3b679SAndreas Boehler                'uri' => $row['uri'],
113*a1a3b679SAndreas Boehler            ];
114*a1a3b679SAndreas Boehler            foreach ($this->fieldMap as $key => $value) {
115*a1a3b679SAndreas Boehler                if ($row[$value['dbField']]) {
116*a1a3b679SAndreas Boehler                    $principal[$key] = $row[$value['dbField']];
117*a1a3b679SAndreas Boehler                }
118*a1a3b679SAndreas Boehler            }
119*a1a3b679SAndreas Boehler            $principals[] = $principal;
120*a1a3b679SAndreas Boehler
121*a1a3b679SAndreas Boehler        }
122*a1a3b679SAndreas Boehler
123*a1a3b679SAndreas Boehler        return $principals;
124*a1a3b679SAndreas Boehler
125*a1a3b679SAndreas Boehler    }
126*a1a3b679SAndreas Boehler
127*a1a3b679SAndreas Boehler    /**
128*a1a3b679SAndreas Boehler     * Returns a specific principal, specified by it's path.
129*a1a3b679SAndreas Boehler     * The returned structure should be the exact same as from
130*a1a3b679SAndreas Boehler     * getPrincipalsByPrefix.
131*a1a3b679SAndreas Boehler     *
132*a1a3b679SAndreas Boehler     * @param string $path
133*a1a3b679SAndreas Boehler     * @return array
134*a1a3b679SAndreas Boehler     */
135*a1a3b679SAndreas Boehler    function getPrincipalByPath($path) {
136*a1a3b679SAndreas Boehler
137*a1a3b679SAndreas Boehler        $fields = [
138*a1a3b679SAndreas Boehler            'id',
139*a1a3b679SAndreas Boehler            'uri',
140*a1a3b679SAndreas Boehler        ];
141*a1a3b679SAndreas Boehler
142*a1a3b679SAndreas Boehler        foreach ($this->fieldMap as $key => $value) {
143*a1a3b679SAndreas Boehler            $fields[] = $value['dbField'];
144*a1a3b679SAndreas Boehler        }
145*a1a3b679SAndreas Boehler        $stmt = $this->pdo->prepare('SELECT ' . implode(',', $fields) . '  FROM ' . $this->tableName . ' WHERE uri = ?');
146*a1a3b679SAndreas Boehler        $stmt->execute([$path]);
147*a1a3b679SAndreas Boehler
148*a1a3b679SAndreas Boehler        $row = $stmt->fetch(\PDO::FETCH_ASSOC);
149*a1a3b679SAndreas Boehler        if (!$row) return;
150*a1a3b679SAndreas Boehler
151*a1a3b679SAndreas Boehler        $principal = [
152*a1a3b679SAndreas Boehler            'id'  => $row['id'],
153*a1a3b679SAndreas Boehler            'uri' => $row['uri'],
154*a1a3b679SAndreas Boehler        ];
155*a1a3b679SAndreas Boehler        foreach ($this->fieldMap as $key => $value) {
156*a1a3b679SAndreas Boehler            if ($row[$value['dbField']]) {
157*a1a3b679SAndreas Boehler                $principal[$key] = $row[$value['dbField']];
158*a1a3b679SAndreas Boehler            }
159*a1a3b679SAndreas Boehler        }
160*a1a3b679SAndreas Boehler        return $principal;
161*a1a3b679SAndreas Boehler
162*a1a3b679SAndreas Boehler    }
163*a1a3b679SAndreas Boehler
164*a1a3b679SAndreas Boehler    /**
165*a1a3b679SAndreas Boehler     * Updates one ore more webdav properties on a principal.
166*a1a3b679SAndreas Boehler     *
167*a1a3b679SAndreas Boehler     * The list of mutations is stored in a Sabre\DAV\PropPatch object.
168*a1a3b679SAndreas Boehler     * To do the actual updates, you must tell this object which properties
169*a1a3b679SAndreas Boehler     * you're going to process with the handle() method.
170*a1a3b679SAndreas Boehler     *
171*a1a3b679SAndreas Boehler     * Calling the handle method is like telling the PropPatch object "I
172*a1a3b679SAndreas Boehler     * promise I can handle updating this property".
173*a1a3b679SAndreas Boehler     *
174*a1a3b679SAndreas Boehler     * Read the PropPatch documenation for more info and examples.
175*a1a3b679SAndreas Boehler     *
176*a1a3b679SAndreas Boehler     * @param string $path
177*a1a3b679SAndreas Boehler     * @param DAV\PropPatch $propPatch
178*a1a3b679SAndreas Boehler     */
179*a1a3b679SAndreas Boehler    function updatePrincipal($path, DAV\PropPatch $propPatch) {
180*a1a3b679SAndreas Boehler
181*a1a3b679SAndreas Boehler        $propPatch->handle(array_keys($this->fieldMap), function($properties) use ($path) {
182*a1a3b679SAndreas Boehler
183*a1a3b679SAndreas Boehler            $query = "UPDATE " . $this->tableName . " SET ";
184*a1a3b679SAndreas Boehler            $first = true;
185*a1a3b679SAndreas Boehler
186*a1a3b679SAndreas Boehler            $values = [];
187*a1a3b679SAndreas Boehler
188*a1a3b679SAndreas Boehler            foreach ($properties as $key => $value) {
189*a1a3b679SAndreas Boehler
190*a1a3b679SAndreas Boehler                $dbField = $this->fieldMap[$key]['dbField'];
191*a1a3b679SAndreas Boehler
192*a1a3b679SAndreas Boehler                if (!$first) {
193*a1a3b679SAndreas Boehler                    $query .= ', ';
194*a1a3b679SAndreas Boehler                }
195*a1a3b679SAndreas Boehler                $first = false;
196*a1a3b679SAndreas Boehler                $query .= $dbField . ' = :' . $dbField;
197*a1a3b679SAndreas Boehler                $values[$dbField] = $value;
198*a1a3b679SAndreas Boehler
199*a1a3b679SAndreas Boehler            }
200*a1a3b679SAndreas Boehler
201*a1a3b679SAndreas Boehler            $query .= " WHERE uri = :uri";
202*a1a3b679SAndreas Boehler            $values['uri'] = $path;
203*a1a3b679SAndreas Boehler
204*a1a3b679SAndreas Boehler            $stmt = $this->pdo->prepare($query);
205*a1a3b679SAndreas Boehler            $stmt->execute($values);
206*a1a3b679SAndreas Boehler
207*a1a3b679SAndreas Boehler            return true;
208*a1a3b679SAndreas Boehler
209*a1a3b679SAndreas Boehler        });
210*a1a3b679SAndreas Boehler
211*a1a3b679SAndreas Boehler    }
212*a1a3b679SAndreas Boehler
213*a1a3b679SAndreas Boehler    /**
214*a1a3b679SAndreas Boehler     * This method is used to search for principals matching a set of
215*a1a3b679SAndreas Boehler     * properties.
216*a1a3b679SAndreas Boehler     *
217*a1a3b679SAndreas Boehler     * This search is specifically used by RFC3744's principal-property-search
218*a1a3b679SAndreas Boehler     * REPORT.
219*a1a3b679SAndreas Boehler     *
220*a1a3b679SAndreas Boehler     * The actual search should be a unicode-non-case-sensitive search. The
221*a1a3b679SAndreas Boehler     * keys in searchProperties are the WebDAV property names, while the values
222*a1a3b679SAndreas Boehler     * are the property values to search on.
223*a1a3b679SAndreas Boehler     *
224*a1a3b679SAndreas Boehler     * By default, if multiple properties are submitted to this method, the
225*a1a3b679SAndreas Boehler     * various properties should be combined with 'AND'. If $test is set to
226*a1a3b679SAndreas Boehler     * 'anyof', it should be combined using 'OR'.
227*a1a3b679SAndreas Boehler     *
228*a1a3b679SAndreas Boehler     * This method should simply return an array with full principal uri's.
229*a1a3b679SAndreas Boehler     *
230*a1a3b679SAndreas Boehler     * If somebody attempted to search on a property the backend does not
231*a1a3b679SAndreas Boehler     * support, you should simply return 0 results.
232*a1a3b679SAndreas Boehler     *
233*a1a3b679SAndreas Boehler     * You can also just return 0 results if you choose to not support
234*a1a3b679SAndreas Boehler     * searching at all, but keep in mind that this may stop certain features
235*a1a3b679SAndreas Boehler     * from working.
236*a1a3b679SAndreas Boehler     *
237*a1a3b679SAndreas Boehler     * @param string $prefixPath
238*a1a3b679SAndreas Boehler     * @param array $searchProperties
239*a1a3b679SAndreas Boehler     * @param string $test
240*a1a3b679SAndreas Boehler     * @return array
241*a1a3b679SAndreas Boehler     */
242*a1a3b679SAndreas Boehler    function searchPrincipals($prefixPath, array $searchProperties, $test = 'allof') {
243*a1a3b679SAndreas Boehler
244*a1a3b679SAndreas Boehler        $query = 'SELECT uri FROM ' . $this->tableName . ' WHERE 1=1 ';
245*a1a3b679SAndreas Boehler        $values = [];
246*a1a3b679SAndreas Boehler        foreach ($searchProperties as $property => $value) {
247*a1a3b679SAndreas Boehler
248*a1a3b679SAndreas Boehler            switch ($property) {
249*a1a3b679SAndreas Boehler
250*a1a3b679SAndreas Boehler                case '{DAV:}displayname' :
251*a1a3b679SAndreas Boehler                    $query .= ' AND displayname LIKE ?';
252*a1a3b679SAndreas Boehler                    $values[] = '%' . $value . '%';
253*a1a3b679SAndreas Boehler                    break;
254*a1a3b679SAndreas Boehler                case '{http://sabredav.org/ns}email-address' :
255*a1a3b679SAndreas Boehler                    $query .= ' AND email LIKE ?';
256*a1a3b679SAndreas Boehler                    $values[] = '%' . $value . '%';
257*a1a3b679SAndreas Boehler                    break;
258*a1a3b679SAndreas Boehler                default :
259*a1a3b679SAndreas Boehler                    // Unsupported property
260*a1a3b679SAndreas Boehler                    return [];
261*a1a3b679SAndreas Boehler
262*a1a3b679SAndreas Boehler            }
263*a1a3b679SAndreas Boehler
264*a1a3b679SAndreas Boehler        }
265*a1a3b679SAndreas Boehler        $stmt = $this->pdo->prepare($query);
266*a1a3b679SAndreas Boehler        $stmt->execute($values);
267*a1a3b679SAndreas Boehler
268*a1a3b679SAndreas Boehler        $principals = [];
269*a1a3b679SAndreas Boehler        while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
270*a1a3b679SAndreas Boehler
271*a1a3b679SAndreas Boehler            // Checking if the principal is in the prefix
272*a1a3b679SAndreas Boehler            list($rowPrefix) = URLUtil::splitPath($row['uri']);
273*a1a3b679SAndreas Boehler            if ($rowPrefix !== $prefixPath) continue;
274*a1a3b679SAndreas Boehler
275*a1a3b679SAndreas Boehler            $principals[] = $row['uri'];
276*a1a3b679SAndreas Boehler
277*a1a3b679SAndreas Boehler        }
278*a1a3b679SAndreas Boehler
279*a1a3b679SAndreas Boehler        return $principals;
280*a1a3b679SAndreas Boehler
281*a1a3b679SAndreas Boehler    }
282*a1a3b679SAndreas Boehler
283*a1a3b679SAndreas Boehler    /**
284*a1a3b679SAndreas Boehler     * Returns the list of members for a group-principal
285*a1a3b679SAndreas Boehler     *
286*a1a3b679SAndreas Boehler     * @param string $principal
287*a1a3b679SAndreas Boehler     * @return array
288*a1a3b679SAndreas Boehler     */
289*a1a3b679SAndreas Boehler    function getGroupMemberSet($principal) {
290*a1a3b679SAndreas Boehler
291*a1a3b679SAndreas Boehler        $principal = $this->getPrincipalByPath($principal);
292*a1a3b679SAndreas Boehler        if (!$principal) throw new DAV\Exception('Principal not found');
293*a1a3b679SAndreas Boehler
294*a1a3b679SAndreas Boehler        $stmt = $this->pdo->prepare('SELECT principals.uri as uri FROM ' . $this->groupMembersTableName . ' AS groupmembers LEFT JOIN ' . $this->tableName . ' AS principals ON groupmembers.member_id = principals.id WHERE groupmembers.principal_id = ?');
295*a1a3b679SAndreas Boehler        $stmt->execute([$principal['id']]);
296*a1a3b679SAndreas Boehler
297*a1a3b679SAndreas Boehler        $result = [];
298*a1a3b679SAndreas Boehler        while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
299*a1a3b679SAndreas Boehler            $result[] = $row['uri'];
300*a1a3b679SAndreas Boehler        }
301*a1a3b679SAndreas Boehler        return $result;
302*a1a3b679SAndreas Boehler
303*a1a3b679SAndreas Boehler    }
304*a1a3b679SAndreas Boehler
305*a1a3b679SAndreas Boehler    /**
306*a1a3b679SAndreas Boehler     * Returns the list of groups a principal is a member of
307*a1a3b679SAndreas Boehler     *
308*a1a3b679SAndreas Boehler     * @param string $principal
309*a1a3b679SAndreas Boehler     * @return array
310*a1a3b679SAndreas Boehler     */
311*a1a3b679SAndreas Boehler    function getGroupMembership($principal) {
312*a1a3b679SAndreas Boehler
313*a1a3b679SAndreas Boehler        $principal = $this->getPrincipalByPath($principal);
314*a1a3b679SAndreas Boehler        if (!$principal) throw new DAV\Exception('Principal not found');
315*a1a3b679SAndreas Boehler
316*a1a3b679SAndreas Boehler        $stmt = $this->pdo->prepare('SELECT principals.uri as uri FROM ' . $this->groupMembersTableName . ' AS groupmembers LEFT JOIN ' . $this->tableName . ' AS principals ON groupmembers.principal_id = principals.id WHERE groupmembers.member_id = ?');
317*a1a3b679SAndreas Boehler        $stmt->execute([$principal['id']]);
318*a1a3b679SAndreas Boehler
319*a1a3b679SAndreas Boehler        $result = [];
320*a1a3b679SAndreas Boehler        while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
321*a1a3b679SAndreas Boehler            $result[] = $row['uri'];
322*a1a3b679SAndreas Boehler        }
323*a1a3b679SAndreas Boehler        return $result;
324*a1a3b679SAndreas Boehler
325*a1a3b679SAndreas Boehler    }
326*a1a3b679SAndreas Boehler
327*a1a3b679SAndreas Boehler    /**
328*a1a3b679SAndreas Boehler     * Updates the list of group members for a group principal.
329*a1a3b679SAndreas Boehler     *
330*a1a3b679SAndreas Boehler     * The principals should be passed as a list of uri's.
331*a1a3b679SAndreas Boehler     *
332*a1a3b679SAndreas Boehler     * @param string $principal
333*a1a3b679SAndreas Boehler     * @param array $members
334*a1a3b679SAndreas Boehler     * @return void
335*a1a3b679SAndreas Boehler     */
336*a1a3b679SAndreas Boehler    function setGroupMemberSet($principal, array $members) {
337*a1a3b679SAndreas Boehler
338*a1a3b679SAndreas Boehler        // Grabbing the list of principal id's.
339*a1a3b679SAndreas Boehler        $stmt = $this->pdo->prepare('SELECT id, uri FROM ' . $this->tableName . ' WHERE uri IN (? ' . str_repeat(', ? ', count($members)) . ');');
340*a1a3b679SAndreas Boehler        $stmt->execute(array_merge([$principal], $members));
341*a1a3b679SAndreas Boehler
342*a1a3b679SAndreas Boehler        $memberIds = [];
343*a1a3b679SAndreas Boehler        $principalId = null;
344*a1a3b679SAndreas Boehler
345*a1a3b679SAndreas Boehler        while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
346*a1a3b679SAndreas Boehler            if ($row['uri'] == $principal) {
347*a1a3b679SAndreas Boehler                $principalId = $row['id'];
348*a1a3b679SAndreas Boehler            } else {
349*a1a3b679SAndreas Boehler                $memberIds[] = $row['id'];
350*a1a3b679SAndreas Boehler            }
351*a1a3b679SAndreas Boehler        }
352*a1a3b679SAndreas Boehler        if (!$principalId) throw new DAV\Exception('Principal not found');
353*a1a3b679SAndreas Boehler
354*a1a3b679SAndreas Boehler        // Wiping out old members
355*a1a3b679SAndreas Boehler        $stmt = $this->pdo->prepare('DELETE FROM ' . $this->groupMembersTableName . ' WHERE principal_id = ?;');
356*a1a3b679SAndreas Boehler        $stmt->execute([$principalId]);
357*a1a3b679SAndreas Boehler
358*a1a3b679SAndreas Boehler        foreach ($memberIds as $memberId) {
359*a1a3b679SAndreas Boehler
360*a1a3b679SAndreas Boehler            $stmt = $this->pdo->prepare('INSERT INTO ' . $this->groupMembersTableName . ' (principal_id, member_id) VALUES (?, ?);');
361*a1a3b679SAndreas Boehler            $stmt->execute([$principalId, $memberId]);
362*a1a3b679SAndreas Boehler
363*a1a3b679SAndreas Boehler        }
364*a1a3b679SAndreas Boehler
365*a1a3b679SAndreas Boehler    }
366*a1a3b679SAndreas Boehler
367*a1a3b679SAndreas Boehler    /**
368*a1a3b679SAndreas Boehler     * Creates a new principal.
369*a1a3b679SAndreas Boehler     *
370*a1a3b679SAndreas Boehler     * This method receives a full path for the new principal. The mkCol object
371*a1a3b679SAndreas Boehler     * contains any additional webdav properties specified during the creation
372*a1a3b679SAndreas Boehler     * of the principal.
373*a1a3b679SAndreas Boehler     *
374*a1a3b679SAndreas Boehler     * @param string $path
375*a1a3b679SAndreas Boehler     * @param MkCol $mkCol
376*a1a3b679SAndreas Boehler     * @return void
377*a1a3b679SAndreas Boehler     */
378*a1a3b679SAndreas Boehler    function createPrincipal($path, MkCol $mkCol) {
379*a1a3b679SAndreas Boehler
380*a1a3b679SAndreas Boehler        $stmt = $this->pdo->prepare('INSERT INTO ' . $this->tableName . ' (uri) VALUES (?)');
381*a1a3b679SAndreas Boehler        $stmt->execute([$path]);
382*a1a3b679SAndreas Boehler        $this->updatePrincipal($path, $mkCol);
383*a1a3b679SAndreas Boehler
384*a1a3b679SAndreas Boehler    }
385*a1a3b679SAndreas Boehler
386*a1a3b679SAndreas Boehler}
387