Refactor: move common routines into separate methods
[cacert-mgr.git] / manager / application / controllers / ManageAccountController.php
1 <?php
2 /**
3 * @author Michael Tänzer
4 */
5
6 class ManageAccountController extends Zend_Controller_Action
7 {
8 const MAX_POINTS_PER_ASSURANCE = 35;
9 const MAX_ASSURANCE_POINTS = 100;
10
11 protected $db;
12
13 public function init()
14 {
15 $config = new Zend_Config_Ini(APPLICATION_PATH . '/configs/application.ini',
16 APPLICATION_ENV);
17
18 $this->db = Zend_Db::factory($config->ca_mgr->db->auth->pdo,
19 $config->ca_mgr->db->auth);
20 }
21
22 public function indexAction()
23 {
24 // Just render the view
25 return;
26 }
27
28 public function assuranceAction()
29 {
30 // Validate form
31 $form = $this->getAssuranceForm();
32 if (!$this->getRequest()->isPost() || !$form->isValid($_POST)) {
33 $this->view->assurance_form = $form;
34 return $this->render('assuranceform');
35 }
36
37 // Form is valid -> get values for processing
38 $values = $form->getValues();
39
40 // Get user data
41 $user['id'] = $this->getUserId();
42 $user['points'] = $this->getPoints($user['id']);
43
44
45 // Do the actual assurances
46 $assurance = array(); // Make sure the array is empty
47 $assurance['to'] = $user['id'];
48 $assurance['location'] = $values['location'];
49 $assurance['date'] = $values['date'];
50 $assurance['when'] = new Zend_Db_Expr('now()');
51 $this->view->assurancesDone = array();
52
53 $quantity = $values['quantity'];
54 do {
55 // split up into multiple assurances
56 if ($quantity > self::MAX_POINTS_PER_ASSURANCE) {
57 $assurance['awarded'] = self::MAX_POINTS_PER_ASSURANCE;
58 $quantity -= self::MAX_POINTS_PER_ASSURANCE;
59 } else {
60 $assurance['awarded'] = $quantity;
61 $quantity = 0;
62 }
63
64 // Get the assurer for this assurance
65 $assurance['from'] = $this->getNewAssurer($user['id']);
66
67 // only assign points whithin the limit
68 if ($user['points'] + $assurance['awarded'] > self::MAX_ASSURANCE_POINTS){
69 $assurance['points'] = self::MAX_ASSURANCE_POINTS - $user['points'];
70 } else {
71 $assurance['points'] = $assurance['awarded'];
72 }
73
74 $this->db->insert('notary', $assurance);
75
76 $user['points'] += $assurance['points'];
77 $this->view->assurancesDone[] = $assurance['points'];
78 } while ($quantity > 0);
79
80
81 // Maybe user is now assurer
82 $this->fixAssurerFlag($user['id']);
83
84 return;
85 }
86
87 /**
88 * Get and check the user ID of the current user
89 *
90 * @return int The ID of the current user
91 */
92 protected function getUserId()
93 {
94 $session = Zend_Registry::get('session');
95 if ($session->authdata['authed'] !== true) {
96 throw new Exception(__METHOD__ . ': you need to log in to use this feature');
97 }
98
99 // Check if the ID is present on the test server
100 $query = 'select `id` from `users` where `id` = :user';
101 $query_params['user'] = $session->authdata['authed_id'];
102 $result = $this->db->query($query, $query_params);
103 if ($result->rowCount() !== 1) {
104 throw new Exception(__METHOD__ . ': user ID not found in the data base');
105 }
106 $row = $result->fetch();
107
108 return $row['id'];
109 }
110
111 /**
112 * Get current points of the user
113 *
114 * @param int $user_id ID of the user
115 * @return int the amount of points the user currently has
116 */
117 protected function getPoints($user_id)
118 {
119 $query = 'select sum(`points`) as `total` from `notary` where `to` = :user';
120 $query_params['user'] = $user_id;
121 $row = $this->db->query($query, $query_params)->fetch();
122 if ($row['total'] === NULL) $row['total'] = 0;
123
124 return $row['total'];
125 }
126
127 /**
128 * Get the first assurer who didn't already assure the user
129 *
130 * @param int $user_id The ID of the user who should get assured
131 * @return int The ID of the selected assurer
132 */
133 protected function getNewAssurer($user_id)
134 {
135 $query = 'select min(`id`) as `assurer` from `users` ' .
136 'where `email` like \'john.doe-___@example.com\' and ' .
137 '`id` not in (select `from` from `notary` where `to` = :user)';
138 $query_params['user'] = $user_id;
139 $row = $this->db->query($query, $query_params)->fetch();
140
141 if ($row['assurer'] === NULL) {
142 throw new Exception(__METHOD__ . ': no more assurers that haven\'t '.
143 'already assured this account');
144 }
145
146 return $row['assurer'];
147 }
148
149 /**
150 * Fix the assurer flag for the given user
151 *
152 * @param $user_id ID of the user
153 */
154 protected function fixAssurerFlag($user_id)
155 {
156 // TODO: unset flag if requirements are not met
157
158 $query = 'UPDATE `users` SET `assurer` = 1 WHERE `users`.`id` = :user AND '.
159
160 'EXISTS(SELECT * FROM `cats_passed` AS `cp`, `cats_variant` AS `cv` '.
161 'WHERE `cp`.`variant_id` = `cv`.`id` AND `cv`.`type_id` = 1 AND '.
162 '`cp`.`user_id` = :user) AND '.
163
164 '(SELECT SUM(`points`) FROM `notary` WHERE `to` = :user AND '.
165 '`expire` < now()) >= 100';
166 $query_params['user'] = $user_id;
167 $this->db->query($query, $query_params);
168 }
169
170 protected function getAssuranceForm()
171 {
172 $form = new Zend_Form();
173 $form->setAction('/manage-account/assurance')->setMethod('post');
174
175 $quantity = new Zend_Form_Element_Text('quantity');
176 $quantity->setRequired(true)
177 ->setLabel(I18n::_('Number of Points'))
178 ->addFilter(new Zend_Filter_Int())
179 ->addValidator(new Zend_Validate_Between(0, 100));
180 $form->addElement($quantity);
181
182 $location = new Zend_Form_Element_Text('location');
183 $location->setRequired(true)
184 ->setLabel(I18n::_('Location'))
185 ->setValue(I18n::_('CAcert Test Manager'))
186 ->addValidator(new Zend_Validate_StringLength(1,255));
187 $form->addElement($location);
188
189 $date = new Zend_Form_Element_Text('date');
190 $date->setRequired(true)
191 ->setLabel(I18n::_('Date of Assurance'))
192 ->setValue(date('Y-m-d H:i:s'))
193 ->addValidator(new Zend_Validate_StringLength(1,255));
194 $form->addElement($date);
195
196 $submit = new Zend_Form_Element_Submit('submit');
197 $submit->setLabel(I18n::_('Assure Me'));
198 $form->addElement($submit);
199
200 return $form;
201 }
202
203 protected function getAdminIncreaseForm()
204 {
205 $form = new Zend_Form();
206 $form->setAction('/manage-account/admin-increase')->setMethod('post');
207
208 $quantity = new Zend_Form_Element_Text('quantity');
209 $quantity->setRequired(true)
210 ->setLabel(I18n::_('Number of Points'))
211 ->addFilter(new Zend_Filter_Int())
212 ->addValidator(new Zend_Validate_GreaterThan(0));
213 $form->addElement($quantity);
214
215 $fragment = new Zend_Form_Element_Checkbox('fragment');
216 $fragment->setLabel(I18n::_('Split into 2-Point Fragments'))
217 ->setChecked(true);
218 $form->addElement($fragment);
219
220 $unlimited = new Zend_Form_Element_Checkbox('unlimited');
221 $unlimited->setLabel(I18n::_('Assign Points even if the Limit of 150 '.
222 'is exceeded'))
223 ->setChecked(false);
224 $form->addElement($unlimited);
225
226 $location = new Zend_Form_Element_Text('location');
227 $location->setRequired(true)
228 ->setLabel(I18n::_('Location'))
229 ->setValue(I18n::_('CAcert Test Manager'))
230 ->addValidator(new Zend_Validate_StringLength(1,255));
231 $form->addElement($location);
232
233 $date = new Zend_Form_Element_Text('date');
234 $date->setRequired(true)
235 ->setLabel(I18n::_('Date of Increase'))
236 ->setValue(date('Y-m-d H:i:s'))
237 ->addValidator(new Zend_Validate_StringLength(1,255));
238 $form->addElement($date);
239
240 $submit = new Zend_Form_Element_Submit('submit');
241 $submit->setLabel(I18n::_('Give Me Points'));
242 $form->addElement($submit);
243 }
244 }