1<?php
2/* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4/**
5 * a bookable ressource
6 *
7 * @author Jörg Lützenkirchen <luetzenkirchen@leifos.com>
8 * @version $Id$
9 *
10 * @ingroup ModulesBookingManager
11 */
12class ilBookingObject
13{
14    /**
15     * @var ilDB
16     */
17    protected $db;
18
19    protected $id;			// int
20    protected $pool_id;		// int
21    protected $title;		// string
22    protected $description; // string
23    protected $nr_of_items; // int
24    protected $schedule_id; // int
25    protected $info_file; // string
26    protected $post_text; // string
27    protected $post_file; // string
28
29    /**
30     * Constructor
31     *
32     * if id is given will read dataset from db
33     *
34     * @param	int	$a_id
35     */
36    public function __construct($a_id = null)
37    {
38        global $DIC;
39
40        $this->db = $DIC->database();
41        $this->id = (int) $a_id;
42        $this->read();
43    }
44
45    /**
46     * Get id
47     * @return int
48     */
49    public function getId()
50    {
51        return $this->id;
52    }
53
54    /**
55     * Set object title
56     * @param	string	$a_title
57     */
58    public function setTitle($a_title)
59    {
60        $this->title = $a_title;
61    }
62
63    /**
64     * Get object title
65     * @return	string
66     */
67    public function getTitle()
68    {
69        return $this->title;
70    }
71
72    /**
73     * Set object description
74     * @param	string	$a_value
75     */
76    public function setDescription($a_value)
77    {
78        $this->description = $a_value;
79    }
80
81    /**
82     * Get object description
83     * @return	string
84     */
85    public function getDescription()
86    {
87        return $this->description;
88    }
89
90    /**
91     * Set booking pool id
92     * @param	int	$a_pool_id
93     */
94    public function setPoolId($a_pool_id)
95    {
96        $this->pool_id = (int) $a_pool_id;
97    }
98
99    /**
100     * Get booking pool id
101     * @return	int
102     */
103    public function getPoolId()
104    {
105        return $this->pool_id;
106    }
107
108    /**
109     * Set booking schedule id
110     * @param	int	$a_schedule_id
111     */
112    public function setScheduleId($a_schedule_id)
113    {
114        $this->schedule_id = (int) $a_schedule_id;
115    }
116
117    /**
118     * Get booking schedule id
119     * @return	int
120     */
121    public function getScheduleId()
122    {
123        return $this->schedule_id;
124    }
125
126    /**
127     * Set number of items
128     * @param	int	$a_value
129     */
130    public function setNrOfItems($a_value)
131    {
132        $this->nr_of_items = (int) $a_value;
133    }
134
135    /**
136     * Get number of items
137     * @return	int
138     */
139    public function getNrOfItems()
140    {
141        return $this->nr_of_items;
142    }
143
144    /**
145     * Set info file
146     * @param	string	$a_value
147     */
148    public function setFile($a_value)
149    {
150        $this->info_file = $a_value;
151    }
152
153    /**
154     * Get info file
155     * @return	string
156     */
157    public function getFile()
158    {
159        return $this->info_file;
160    }
161
162    /**
163     * Get path to info file
164     */
165    public function getFileFullPath()
166    {
167        if ($this->id && $this->info_file) {
168            $path = $this->initStorage($this->id, "file");
169            return $path . $this->info_file;
170        }
171    }
172
173    /**
174     * Upload new info file
175     *
176     * @param array $a_upload
177     * @return bool
178     */
179    public function uploadFile(array $a_upload)
180    {
181        if (!$this->id) {
182            return false;
183        }
184
185        $this->deleteFile();
186
187        $path = $this->initStorage($this->id, "file");
188        $original = $a_upload["name"];
189        if (ilUtil::moveUploadedFile($a_upload["tmp_name"], $original, $path . $original)) {
190            chmod($path . $original, 0770);
191
192            $this->setFile($original);
193            return true;
194        }
195        return false;
196    }
197
198    /**
199     * remove existing info file
200     */
201    public function deleteFile()
202    {
203        if ($this->id) {
204            $path = $this->getFileFullPath();
205            if ($path) {
206                @unlink($path);
207                $this->setFile(null);
208            }
209        }
210    }
211
212    /**
213     * Set post text
214     * @param	string	$a_value
215     */
216    public function setPostText($a_value)
217    {
218        $this->post_text = $a_value;
219    }
220
221    /**
222     * Get post text
223     * @return	string
224     */
225    public function getPostText()
226    {
227        return $this->post_text;
228    }
229
230    /**
231     * Set post file
232     * @param	string	$a_value
233     */
234    public function setPostFile($a_value)
235    {
236        $this->post_file = $a_value;
237    }
238
239    /**
240     * Get post file
241     * @return	string
242     */
243    public function getPostFile()
244    {
245        return $this->post_file;
246    }
247
248    /**
249     * Get path to post file
250     */
251    public function getPostFileFullPath()
252    {
253        if ($this->id && $this->post_file) {
254            $path = $this->initStorage($this->id, "post");
255            return $path . $this->post_file;
256        }
257    }
258
259    /**
260     * Upload new post file
261     *
262     * @param array $a_upload
263     * @return bool
264     */
265    public function uploadPostFile(array $a_upload)
266    {
267        if (!$this->id) {
268            return false;
269        }
270
271        $this->deletePostFile();
272
273        $path = $this->initStorage($this->id, "post");
274        $original = $a_upload["name"];
275
276        if (ilUtil::moveUploadedFile($a_upload["tmp_name"], $original, $path . $original)) {
277            chmod($path . $original, 0770);
278
279            $this->setPostFile($original);
280            return true;
281        }
282        return false;
283    }
284
285    /**
286     * remove existing post file
287     */
288    public function deletePostFile()
289    {
290        if ($this->id) {
291            $path = $this->getPostFileFullPath();
292            if ($path) {
293                @unlink($path);
294                $this->setPostFile(null);
295            }
296        }
297    }
298
299    /**
300     * remove existing files
301     */
302    public function deleteFiles()
303    {
304        if ($this->id) {
305            $storage = new ilFSStorageBooking($this->id);
306            $storage->delete();
307
308            $this->setFile(null);
309            $this->setPostFile(null);
310        }
311    }
312
313    /**
314     * Init file system storage
315     *
316     * @param type $a_id
317     * @param type $a_subdir
318     * @return string
319     */
320    public static function initStorage($a_id, $a_subdir = null)
321    {
322        $storage = new ilFSStorageBooking($a_id);
323        $storage->create();
324
325        $path = $storage->getAbsolutePath() . "/";
326
327        if ($a_subdir) {
328            $path .= $a_subdir . "/";
329
330            if (!is_dir($path)) {
331                mkdir($path);
332            }
333        }
334
335        return $path;
336    }
337
338    /**
339     * Get dataset from db
340     */
341    protected function read()
342    {
343        $ilDB = $this->db;
344
345        if ($this->id) {
346            $set = $ilDB->query('SELECT *' .
347                ' FROM booking_object' .
348                ' WHERE booking_object_id = ' . $ilDB->quote($this->id, 'integer'));
349            $row = $ilDB->fetchAssoc($set);
350            $this->setTitle($row['title']);
351            $this->setDescription($row['description']);
352            $this->setPoolId($row['pool_id']);
353            $this->setScheduleId($row['schedule_id']);
354            $this->setNrOfItems($row['nr_items']);
355            $this->setFile($row['info_file']);
356            $this->setPostText($row['post_text']);
357            $this->setPostFile($row['post_file']);
358        }
359    }
360
361    /**
362     * Parse properties for sql statements
363     * @return array
364     */
365    protected function getDBFields()
366    {
367        $fields = array(
368            'title' => array('text', $this->getTitle()),
369            'description' => array('text', $this->getDescription()),
370            'schedule_id' => array('text', $this->getScheduleId()),
371            'nr_items' => array('text', $this->getNrOfItems()),
372            'info_file' => array('text', $this->getFile()),
373            'post_text' => array('text', $this->getPostText()),
374            'post_file' => array('text', $this->getPostFile())
375        );
376
377        return $fields;
378    }
379
380    /**
381     * Create new entry in db
382     * @return	bool
383     */
384    public function save()
385    {
386        $ilDB = $this->db;
387
388        if ($this->id) {
389            return false;
390        }
391
392        $this->id = $ilDB->nextId('booking_object');
393
394        $fields = $this->getDBFields();
395        $fields['booking_object_id'] = array('integer', $this->id);
396        $fields['pool_id'] = array('integer', $this->getPoolId());
397
398        return $ilDB->insert('booking_object', $fields);
399    }
400
401    /**
402     * Update entry in db
403     * @return	bool
404     */
405    public function update()
406    {
407        $ilDB = $this->db;
408
409        if (!$this->id) {
410            return false;
411        }
412
413        $fields = $this->getDBFields();
414
415        return $ilDB->update(
416            'booking_object',
417            $fields,
418            array('booking_object_id' => array('integer', $this->id))
419        );
420    }
421
422    /**
423     * Get list of booking objects for given type
424     * @param	int	$a_pool_id
425     * @param	string	$a_title
426     * @return	array
427     */
428    public static function getList($a_pool_id, $a_title = null)
429    {
430        global $DIC;
431
432        $ilDB = $DIC->database();
433
434        $sql = 'SELECT *' .
435            ' FROM booking_object' .
436            ' WHERE pool_id = ' . $ilDB->quote($a_pool_id, 'integer');
437
438        if ($a_title) {
439            $sql .= ' AND (' . $ilDB->like('title', 'text', '%' . $a_title . '%') .
440                ' OR ' . $ilDB->like('description', 'text', '%' . $a_title . '%') . ')';
441        }
442
443        $sql .= ' ORDER BY title';
444
445        $set = $ilDB->query($sql);
446        $res = array();
447        while ($row = $ilDB->fetchAssoc($set)) {
448            $res[] = $row;
449        }
450        return $res;
451    }
452
453    /**
454     * Get number of booking objects for given booking pool id.
455     * @param	int	$a_pool_id
456     * @return	int
457     */
458    public static function getNumberOfObjectsForPool($a_pool_id)
459    {
460        global $DIC;
461
462        $ilDB = $DIC->database();
463
464        $sql = 'SELECT count(*) as count' .
465            ' FROM booking_object' .
466            ' WHERE pool_id = ' . $ilDB->quote($a_pool_id, 'integer');
467        $set = $ilDB->query($sql);
468        $rec = $ilDB->fetchAssoc($set);
469
470        return $rec["count"];
471    }
472
473    /**
474     * Get all booking pool object ids from an specific booking pool.
475     * @param int $a_pool_id
476     * @return array
477     */
478    public static function getObjectsForPool(int $a_pool_id) : array
479    {
480        global $DIC;
481        $ilDB = $DIC->database();
482
483        $set = $ilDB->query("SELECT booking_object_id" .
484            " FROM booking_object" .
485            " WHERE pool_id = " . $ilDB->quote($a_pool_id, 'integer'));
486
487        $objects = array();
488        while ($row = $ilDB->fetchAssoc($set)) {
489            $objects[] = $row['booking_object_id'];
490        }
491
492        return $objects;
493    }
494
495
496    /**
497     * Delete single entry
498     * @return bool
499     */
500    public function delete()
501    {
502        $ilDB = $this->db;
503
504        if ($this->id) {
505            $this->deleteFiles();
506
507            return $ilDB->manipulate('DELETE FROM booking_object' .
508                ' WHERE booking_object_id = ' . $ilDB->quote($this->id, 'integer'));
509        }
510    }
511
512    /**
513     * Get nr of available items
514     * @param array $a_obj_ids
515     * @return array
516     */
517    public static function getNrOfItemsForObjects(array $a_obj_ids)
518    {
519        global $DIC;
520
521        $ilDB = $DIC->database();
522
523        $map = array();
524
525        $set = $ilDB->query("SELECT booking_object_id,nr_items" .
526            " FROM booking_object" .
527            " WHERE " . $ilDB->in("booking_object_id", $a_obj_ids, "", "integer"));
528        while ($row = $ilDB->fetchAssoc($set)) {
529            $map[$row["booking_object_id"]] = $row["nr_items"];
530        }
531
532        return $map;
533    }
534
535    public function doClone($a_pool_id, $a_schedule_map = null)
536    {
537        $new_obj = new self();
538        $new_obj->setPoolId($a_pool_id);
539        $new_obj->setTitle($this->getTitle());
540        $new_obj->setDescription($this->getDescription());
541        $new_obj->setNrOfItems($this->getNrOfItems());
542        $new_obj->setFile($this->getFile());
543        $new_obj->setPostText($this->getPostText());
544        $new_obj->setPostFile($this->getPostFile());
545
546        if ($a_schedule_map) {
547            $schedule_id = $this->getScheduleId();
548            if ($schedule_id) {
549                $new_obj->setScheduleId($a_schedule_map[$schedule_id]);
550            }
551        }
552
553        $new_obj->save();
554
555        // files
556        $source = $this->initStorage($this->getId());
557        $target = $new_obj->initStorage($new_obj->getId());
558        ilUtil::rCopy($source, $target);
559    }
560
561    /**
562     * Lookup pool id
563     *
564     * @param int $object_id
565     * @return int
566     */
567    public static function lookupPoolId($object_id)
568    {
569        global $DIC;
570
571        $db = $DIC->database();
572        $set = $db->queryF(
573            "SELECT pool_id FROM booking_object " .
574            " WHERE booking_object_id = %s ",
575            array("integer"),
576            array($object_id)
577        );
578        $rec = $db->fetchAssoc($set);
579        return (int) $rec["pool_id"];
580    }
581
582    /**
583     * Lookup pool id
584     *
585     * @param int $object_id
586     * @return int
587     */
588    public static function lookupTitle($object_id)
589    {
590        global $DIC;
591
592        $db = $DIC->database();
593        $set = $db->queryF(
594            "SELECT title FROM booking_object " .
595            " WHERE booking_object_id = %s ",
596            array("integer"),
597            array($object_id)
598        );
599        $rec = $db->fetchAssoc($set);
600        return $rec["title"];
601    }
602}
603