Passed
Pull Request — dev (#6)
by Rafael
79:24 queued 24:08
created

CdavLib::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 3
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
/* Copyright (C) 2018       Destailleur Laurent         <[email protected]>
4
 * Copyright (C) 2024       Frédéric France             <[email protected]>
5
 * Copyright (C) 2024       Rafael San José             <[email protected]>
6
 *
7
 * This program is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19
 */
20
21
namespace Dolibarr\Code\Dav\Classes;
22
23
use DoliDB;
24
25
/**
26
 *      \file       htdocs/dav/dav.class.php
27
 *      \ingroup    dav
28
 *      \brief      Server DAV
29
 */
30
31
32
/**
33
 * Define Common function to access calendar items and format it in vCalendar
34
 */
35
class CdavLib
36
{
37
    /**
38
     * @var DoliDB
39
     */
40
    private $db;
41
42
    /**
43
     * @var User
44
     */
45
    private $user;
46
47
    /**
48
     * @var Translate
49
     */
50
    private $langs; // @phpstan-ignore-line
51
52
    /**
53
     * Constructor
54
     *
55
     * @param   User        $user   user
56
     * @param   DoliDB      $db     Database handler
57
     * @param   Translate   $langs  translation
58
     */
59
    public function __construct($user, $db, $langs)
60
    {
61
        $this->user = $user;
62
        $this->db = $db;
63
        $this->langs = $langs;
64
    }
65
66
    /**
67
     * Base sql request for calendar events
68
     *
69
     * @param   int         $calid          Calendard id
70
     * @param   int|boolean $oid            Oid
71
     * @param   int|boolean $ouri           Ouri
72
     * @return string
73
     */
74
    public function getSqlCalEvents($calid, $oid = false, $ouri = false)
75
    {
76
        // TODO : replace GROUP_CONCAT by
77
        $sql = 'SELECT
78
					a.tms AS lastupd,
79
					a.*,
80
					sp.firstname,
81
					sp.lastname,
82
					sp.address,
83
					sp.zip,
84
					sp.town,
85
					co.label country_label,
86
					sp.phone,
87
					sp.phone_perso,
88
					sp.phone_mobile,
89
					s.nom AS soc_nom,
90
					s.address soc_address,
91
					s.zip soc_zip,
92
					s.town soc_town,
93
					cos.label soc_country_label,
94
					s.phone soc_phone,
95
					ac.sourceuid,
96
					(SELECT GROUP_CONCAT(u.login) FROM ' . MAIN_DB_PREFIX . 'actioncomm_resources ar
97
						LEFT OUTER JOIN ' . MAIN_DB_PREFIX . 'user AS u ON (u.rowid=fk_element)
98
						WHERE ar.element_type=\'user\' AND fk_actioncomm=a.id) AS other_users
99
				FROM ' . MAIN_DB_PREFIX . 'actioncomm AS a';
100
        $sql .= " LEFT JOIN '.MAIN_DB_PREFIX.'c_country as co ON co.rowid = sp.fk_pays
101
				LEFT JOIN '.MAIN_DB_PREFIX.'c_country as cos ON cos.rowid = s.fk_pays
102
				WHERE 	a.id IN (SELECT ar.fk_actioncomm FROM '.MAIN_DB_PREFIX.'actioncomm_resources ar WHERE ar.element_type='user' AND ar.fk_element=" . ((int) $calid) . ")
103
						AND a.code IN (SELECT cac.code FROM '.MAIN_DB_PREFIX.'c_actioncomm cac WHERE cac.type <> 'systemauto')
104
						AND a.entity IN (" . getEntity('societe', 1) . ")";
105
        // TODO Restrict on external users
106
        if ($oid !== false) {
107
            if ($ouri === false) {
108
                $sql .= ' AND a.id = ' . ((int) $oid);
109
            } else {
110
                $sql .= ' AND (a.id = ' . ((int) $oid) . " OR ac.uuidext = '" . $this->db->escape($ouri) . "')";
111
            }
112
        }
113
114
        return $sql;
115
    }
116
117
    /**
118
     * Convert calendar row to VCalendar string
119
     *
120
     * @param   int     $calid      Calendar id
121
     * @param   Object  $obj        Object id
122
     * @return string
123
     */
124
    public function toVCalendar($calid, $obj)
125
    {
126
        /*$categ = array();
127
        if($obj->soc_client)
128
        {
129
            $nick[] = $obj->soc_code_client;
130
            $categ[] = $this->langs->transnoentitiesnoconv('Customer');
131
        }*/
132
133
        $location = $obj->location;
134
135
        // contact address
136
        if (empty($location) && !empty($obj->address)) {
137
            $location = trim(str_replace(array("\r", "\t", "\n"), ' ', $obj->address));
138
            $location = trim($location . ', ' . $obj->zip);
139
            $location = trim($location . ' ' . $obj->town);
140
            $location = trim($location . ', ' . $obj->country_label);
141
        }
142
143
        // contact address
144
        if (empty($location) && !empty($obj->soc_address)) {
145
            $location = trim(str_replace(array("\r", "\t", "\n"), ' ', $obj->soc_address));
146
            $location = trim($location . ', ' . $obj->soc_zip);
147
            $location = trim($location . ' ' . $obj->soc_town);
148
            $location = trim($location . ', ' . $obj->soc_country_label);
149
        }
150
151
        /*
152
        $address = explode("\n", $obj->address, 2);
153
        foreach ($address as $kAddr => $vAddr) {
154
            $address[$kAddr] = trim(str_replace(array("\r", "\t"), ' ', str_replace("\n", ' | ', trim($vAddr))));
155
        }
156
        $address[] = '';
157
        $address[] = '';
158
        */
159
160
        if ($obj->percent == -1 && trim($obj->datep) != '') {
161
            $type = 'VEVENT';
162
        } else {
163
            $type = 'VTODO';
164
        }
165
166
        $timezone = date_default_timezone_get();
167
168
        $caldata = "BEGIN:VCALENDAR\n";
169
        $caldata .= "VERSION:2.0\n";
170
        $caldata .= "METHOD:PUBLISH\n";
171
        $caldata .= "PRODID:-//Dolibarr CDav//FR\n";
172
        $caldata .= "BEGIN:" . $type . "\n";
173
        $caldata .= "CREATED:" . gmdate('Ymd\THis', strtotime($obj->datec)) . "Z\n";
174
        $caldata .= "LAST-MODIFIED:" . gmdate('Ymd\THis', strtotime($obj->lastupd)) . "Z\n";
175
        $caldata .= "DTSTAMP:" . gmdate('Ymd\THis', strtotime($obj->lastupd)) . "Z\n";
176
        if ($obj->sourceuid == '') {
177
            $caldata .= "UID:" . $obj->id . '-ev-' . $calid . '-cal-' . constant('CDAV_URI_KEY') . "\n";
178
        } else {
179
            $caldata .= "UID:" . $obj->sourceuid . "\n";
180
        }
181
        $caldata .= "SUMMARY:" . $obj->label . "\n";
182
        $caldata .= "LOCATION:" . $location . "\n";
183
        $caldata .= "PRIORITY:" . $obj->priority . "\n";
184
        if ($obj->fulldayevent) {
185
            $caldata .= "DTSTART;VALUE=DATE:" . date('Ymd', strtotime($obj->datep)) . "\n";
186
            if ($type == 'VEVENT') {
187
                if (trim($obj->datep2) != '') {
188
                    $caldata .= "DTEND;VALUE=DATE:" . date('Ymd', strtotime($obj->datep2) + 1) . "\n";
189
                } else {
190
                    $caldata .= "DTEND;VALUE=DATE:" . date('Ymd', strtotime($obj->datep) + (25 * 3600)) . "\n";
191
                }
192
            } elseif (trim($obj->datep2) != '') {
193
                $caldata .= "DUE;VALUE=DATE:" . date('Ymd', strtotime($obj->datep2) + 1) . "\n";
194
            }
195
        } else {
196
            $caldata .= "DTSTART;TZID=" . $timezone . ":" . strtr($obj->datep, array(" " => "T", ":" => "", "-" => "")) . "\n";
197
            if ($type == 'VEVENT') {
198
                if (trim($obj->datep2) != '') {
199
                    $caldata .= "DTEND;TZID=" . $timezone . ":" . strtr($obj->datep2, array(" " => "T", ":" => "", "-" => "")) . "\n";
200
                } else {
201
                    $caldata .= "DTEND;TZID=" . $timezone . ":" . strtr($obj->datep, array(" " => "T", ":" => "", "-" => "")) . "\n";
202
                }
203
            } elseif (trim($obj->datep2) != '') {
204
                $caldata .= "DUE;TZID=" . $timezone . ":" . strtr($obj->datep2, array(" " => "T", ":" => "", "-" => "")) . "\n";
205
            }
206
        }
207
        $caldata .= "CLASS:PUBLIC\n";
208
        if ($obj->transparency == 1) {
209
            $caldata .= "TRANSP:TRANSPARENT\n";
210
        } else {
211
            $caldata .= "TRANSP:OPAQUE\n";
212
        }
213
214
        if ($type == 'VEVENT') {
215
            $caldata .= "STATUS:CONFIRMED\n";
216
        } elseif ($obj->percent == 0) {
217
            $caldata .= "STATUS:NEEDS-ACTION\n";
218
        } elseif ($obj->percent == 100) {
219
            $caldata .= "STATUS:COMPLETED\n";
220
        } else {
221
            $caldata .= "STATUS:IN-PROCESS\n";
222
            $caldata .= "PERCENT-COMPLETE:" . $obj->percent . "\n";
223
        }
224
225
        $caldata .= "DESCRIPTION:";
226
        $caldata .= strtr($obj->note, array("\n" => "\\n", "\r" => ""));
227
        if (!empty($obj->soc_nom)) {
228
            $caldata .= "\\n*DOLIBARR-SOC: " . $obj->soc_nom;
229
        }
230
        if (!empty($obj->soc_phone)) {
231
            $caldata .= "\\n*DOLIBARR-SOC-TEL: " . $obj->soc_phone;
232
        }
233
        if (!empty($obj->firstname) || !empty($obj->lastname)) {
234
            $caldata .= "\\n*DOLIBARR-CTC: " . trim($obj->firstname . ' ' . $obj->lastname);
235
        }
236
        if (!empty($obj->phone) || !empty($obj->phone_perso) || !empty($obj->phone_mobile)) {
237
            $caldata .= "\\n*DOLIBARR-CTC-TEL: " . trim($obj->phone . ' ' . $obj->phone_perso . ' ' . $obj->phone_mobile);
238
        }
239
        if (strpos($obj->other_users, ',')) { // several
240
            $caldata .= "\\n*DOLIBARR-USR: " . $obj->other_users;
241
        }
242
        $caldata .= "\n";
243
244
        $caldata .= "END:" . $type . "\n";
245
        $caldata .= "END:VCALENDAR\n";
246
247
        return $caldata;
248
    }
249
250
    /**
251
     * getFullCalendarObjects
252
     *
253
     * @param int       $calendarId         Calendar id
254
     * @param int       $bCalendarData      Add calendar data
255
     * @return array|string[][]
256
     */
257
    public function getFullCalendarObjects($calendarId, $bCalendarData)
258
    {
259
        $calid = (int) $calendarId;
260
        $calevents = array();
261
262
        if (!$this->user->rights->agenda->myactions->read) {
263
            return $calevents;
264
        }
265
266
        if ($calid != $this->user->id && (!isset($this->user->rights->agenda->allactions->read) || !$this->user->rights->agenda->allactions->read)) {
267
            return $calevents;
268
        }
269
270
        $sql = $this->getSqlCalEvents($calid);
271
272
        $result = $this->db->query($sql);
273
274
        if ($result) {
275
            while ($obj = $this->db->fetch_object($result)) {
276
                $calendardata = $this->toVCalendar($calid, $obj);
277
278
                if ($bCalendarData) {
279
                    $calevents[] = array(
280
                        'calendardata' => $calendardata,
281
                        'uri' => $obj->id . '-ev-' . constant('CDAV_URI_KEY'),
282
                        'lastmodified' => strtotime($obj->lastupd),
283
                        'etag' => '"' . md5($calendardata) . '"',
284
                        'calendarid'   => $calendarId,
285
                        'size' => strlen($calendardata),
286
                        'component' => strpos($calendardata, 'BEGIN:VEVENT') > 0 ? 'vevent' : 'vtodo',
287
                    );
288
                } else {
289
                    $calevents[] = array(
290
                        // 'calendardata' => $calendardata,  not necessary because etag+size are present
291
                        'uri' => $obj->id . '-ev-' . constant('CDAV_URI_KEY'),
292
                        'lastmodified' => strtotime($obj->lastupd),
293
                        'etag' => '"' . md5($calendardata) . '"',
294
                        'calendarid'   => $calendarId,
295
                        'size' => strlen($calendardata),
296
                        'component' => strpos($calendardata, 'BEGIN:VEVENT') > 0 ? 'vevent' : 'vtodo',
297
                    );
298
                }
299
            }
300
        }
301
        return $calevents;
302
    }
303
}
304