1<?php
2
3/*
4 +-------------------------------------------------------------------------+
5 | Copyright 2010-2021, Davide Franco			                           |
6 |                                                                         |
7 | This program is free software; you can redistribute it and/or           |
8 | modify it under the terms of the GNU General Public License             |
9 | as published by the Free Software Foundation; either version 2          |
10 | of the License, or (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*/
18
19class VolumesView extends CView
20{
21    public function __construct()
22    {
23        parent::__construct();
24
25        $this->templateName = 'volumes.tpl';
26        $this->name = 'Volumes report';
27        $this->title = 'Bacula volume(s) overview';
28    }
29
30    public function prepare()
31    {
32        $volumes = new Volumes_Model();
33        $volumes_list = array();
34        $volumes_total_bytes = 0;
35        $where = null;
36        $pool_id = 0;
37
38        // Paginate database query result
39        $pagination = new CDBPagination($this);
40
41        // Volumes status icon
42        $volume_status = array( 'Full' => 'fa-battery-full',
43            'Archive' => 'fa-file-archive-o',
44            'Append' => 'fa-battery-quarter',
45            'Recycle' => 'fa-recycle',
46            'Read-Only' => 'fa-lock',
47            'Disabled' => 'fa-ban',
48            'Error' => 'fa-times-circle',
49            'Busy' => 'fa-clock-o',
50            'Used' => 'fa-battery-quarter',
51            'Purged' => 'fa-battery-empty' );
52
53        // Pools list filter
54        $pools = new Pools_Model();
55        $pools_list = array();
56
57        // Create pools list
58        foreach ($pools->getPools() as $pool) {
59            $pools_list[$pool['poolid']] = $pool['name'];
60        }
61
62        $pools_list = array( 0 => 'Any') + $pools_list; // Add defautl pool filter
63        $this->assign('pools_list', $pools_list);
64
65        if (CHttpRequest::get_Value('filter_pool_id') != null) {
66            // Ensure pool_id value is an integer
67            if (!is_numeric(CHttpRequest::get_Value('filter_pool_id')) && !is_null(CHttpRequest::get_Value('filter_pool_id'))) {
68                throw new Exception('Invalid pool id (not numeric) provided in Volumes report page');
69            }
70
71            if (CHttpRequest::get_Value('filter_pool_id') !== '0') {
72                $pool_id = CHttpRequest::get_Value('filter_pool_id');
73                $volumes->addParameter('pool_id', $pool_id);
74                $where[] = 'Media.PoolId = :pool_id';
75            }
76        }
77
78        // Order by
79        $orderby = array('Name' => 'Name', 'MediaId' => 'Id', 'VolBytes' => 'Bytes', 'VolJobs' => 'Jobs');
80
81        // Set order by
82        $this->assign('orderby', $orderby);
83        $volume_orderby_filter = 'Name';
84        $volume_orderby_asc = 'DESC';
85
86        if (!is_null(CHttpRequest::get_Value('orderby'))) {
87            if (array_key_exists(CHttpRequest::get_Value('orderby'), $orderby)) {
88                $volume_orderby_filter = CHttpRequest::get_Value('orderby');
89            } else {
90                throw new Exception("Critical: Provided orderby parameter is not correct");
91            }
92        }
93
94        // Set order by filter and checkbox status
95        $this->assign('orderby_asc_checked', '');
96
97        if (!is_null(CHttpRequest::get_Value('orderby_asc'))) {
98            $volume_orderby_asc = 'ASC';
99            $this->assign('orderby_asc_checked', 'checked');
100        }
101
102        $this->assign('orderby_selected', $volume_orderby_filter);
103
104        // Set inchanger checkbox to unchecked by default
105        $this->assign('inchanger_checked', '');
106
107        if (!is_null(CHttpRequest::get_Value('filter_inchanger'))) {
108            $volumes->addParameter('inchanger', 1);
109            $where[] = 'Media.inchanger = :inchanger';
110            $this->assign('inchanger_checked', 'checked');
111        }
112
113        $fields = array('Media.volumename', 'Media.volbytes', 'Media.voljobs', 'Media.volstatus', 'Media.mediatype', 'Media.lastwritten',
114        'Media.volretention', 'Media.slot', 'Media.inchanger', 'Pool.Name AS pool_name');
115
116        $sqlQuery = CDBQuery::get_Select(array('table' => 'Media',
117                                            'fields' => $fields,
118                                            'orderby' => "$volume_orderby_filter $volume_orderby_asc",
119                                            'join' => array(
120                                                array('table' => 'Pool', 'condition' => 'Media.poolid = Pool.poolid')
121                                            ),
122                                            'where' => $where,
123                                            'limit' => [
124                                                'count' => $pagination->getLimit(),
125                                                'offset' => $pagination->getOffset() ]
126                                            ),$volumes->get_driver_name());
127
128        foreach($pagination->paginate($volumes->run_query($sqlQuery), $volumes->count(), $volumes->count('Media', $where)) as $volume) {
129            // Calculate volume expiration
130            // If volume have already been used
131            if ($volume['lastwritten'] != "0000-00-00 00:00:00") {
132                // Calculate expiration date only if volume status is Full or Used
133                if ($volume['volstatus'] == 'Full' || $volume['volstatus'] == 'Used') {
134                    $expire_date = strtotime($volume['lastwritten']) + $volume['volretention'];
135                    $volume['expire'] = date($_SESSION['datetime_format_short'], $expire_date);
136                } else {
137                    $volume['expire'] = 'n/a';
138                }
139            } else {
140                $volume['expire'] = 'n/a';
141            }
142
143            // Set lastwritten for the volume
144            if (($volume['lastwritten'] == '0000-00-00 00:00:00') || empty($volume['lastwritten'])) {
145                $volume['lastwritten'] = 'n/a';
146            } else {
147                // Format lastwritten in custom format if defined in config file
148                $volume['lastwritten'] = date($_SESSION['datetime_format'], strtotime($volume['lastwritten']));
149            }
150
151            // Sum volumes bytes
152            $volumes_total_bytes += $volume['volbytes'];
153
154            // Get volume used bytes in a human format
155            $volume['volbytes'] = CUtils::Get_Human_Size($volume['volbytes']);
156
157            // Update volume inchanger
158            if ($volume['inchanger'] == '0') {
159                $volume['inchanger'] = '-';
160                $volume['slot'] = 'n/a';
161            } else {
162                $volume['inchanger'] = '<span class="glyphicon glyphicon-ok"></span>';
163            }
164
165            // Set volume status icon
166            $volume['status_icon'] = $volume_status[ $volume['volstatus'] ];
167
168            // Format voljobs
169            $volume['voljobs'] = CUtils::format_Number($volume['voljobs']);
170
171            // add volume in volumes list array
172            $volumes_list[] = $volume;
173        } // end foreach
174
175        $this->assign('pool_id', $pool_id);
176        $this->assign('volumes', $volumes_list);
177
178        $this->assign('volumes_count', $volumes->count());
179        $this->assign('volumes_total_bytes', CUtils::Get_Human_Size($volumes_total_bytes));
180    } // end of preare() method
181} // end of class
182