Fix case on Class names (actually they are case insensitive so this is just a tidy up
[civicrm-core.git] / CRM / Admin / Form / Options.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.4 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2013 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
26 */
27
28 /**
29 *
30 * @package CRM
31 * @copyright CiviCRM LLC (c) 2004-2013
32 * $Id$
33 *
34 */
35
36 /**
37 * This class generates form components for Options
38 *
39 */
40 class CRM_Admin_Form_Options extends CRM_Admin_Form {
41
42 /**
43 * The option group name
44 *
45 * @var array
46 * @static
47 */
48 protected $_gName;
49
50 /**
51 * The option group name in display format (capitalized, without underscores...etc)
52 *
53 * @var array
54 * @static
55 */
56 protected $_GName;
57
58 /**
59 * Function to pre-process
60 *
61 * @return None
62 * @access public
63 */
64 public function preProcess() {
65 parent::preProcess();
66 $session = CRM_Core_Session::singleton();
67 if (!$this->_gName) {
68 $this->_gName = CRM_Utils_Request::retrieve('group', 'String', $this, FALSE, 0);
69 $this->_gid = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionGroup',
70 $this->_gName,
71 'id',
72 'name'
73 );
74 }
75 if ($this->_gName) {
76 $this->set('gName', $this->_gName);
77 }
78 else {
79 $this->_gName = $this->get('gName');
80 }
81 $this->_GName = ucwords(str_replace('_', ' ', $this->_gName));
82 $url = "civicrm/admin/options/{$this->_gName}";
83 $params = "group={$this->_gName}&reset=1";
84
85 if (($this->_action & CRM_Core_Action::DELETE) &&
86 in_array($this->_gName, array('email_greeting', 'postal_greeting', 'addressee'))
87 ) {
88 // Don't allow delete if the option value belongs to addressee, postal or email greetings and is in use.
89 $findValue = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionValue', $this->_id, 'value');
90 $queryParam = array(1 => array($findValue, 'Integer'));
91 $columnName = $this->_gName . "_id";
92 $sql = "SELECT count(id) FROM civicrm_contact WHERE " . $columnName . " = %1";
93 $isInUse = CRM_Core_DAO::singleValueQuery($sql, $queryParam);
94 if ($isInUse) {
95 $scriptURL = "<a href='" . CRM_Utils_System::docURL2('Update Greetings and Address Data for Contacts', TRUE, NULL, NULL, NULL, "wiki") . "'>" . ts('Learn more about a script that can automatically update contact addressee and greeting options.') . "</a>";
96 CRM_Core_Session::setStatus(ts('The selected %1 option has <strong>not been deleted</strong> because it is currently in use. Please update these contacts to use a different format before deleting this option. %2', array(1 => $this->_GName, 2 => $scriptURL)), ts('Sorry'), 'error');
97 $redirect = CRM_Utils_System::url($url, $params);
98 CRM_Utils_System::redirect($redirect);
99 }
100 }
101
102
103 $session->pushUserContext(CRM_Utils_System::url($url, $params));
104 $this->assign('id', $this->_id);
105
106 if ($this->_id && in_array($this->_gName, CRM_Core_OptionGroup::$_domainIDGroups)) {
107 $domainID = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionValue', $this->_id, 'domain_id', 'id');
108 if (CRM_Core_Config::domainID() != $domainID) {
109 CRM_Core_Error::fatal(ts('You do not have permission to access this page'));
110 }
111 }
112 }
113
114 /**
115 * This function sets the default values for the form.
116 * the default values are retrieved from the database
117 *
118 * @access public
119 *
120 * @return None
121 */
122 function setDefaultValues() {
123 $defaults = parent::setDefaultValues();
124
125 if (!isset($defaults['weight']) || !$defaults['weight']) {
126 $fieldValues = array('option_group_id' => $this->_gid);
127 $defaults['weight'] = CRM_Utils_Weight::getDefaultWeight('CRM_Core_DAO_OptionValue', $fieldValues);
128 }
129
130 //setDefault of contact types for email greeting, postal greeting, addressee, CRM-4575
131 if (in_array($this->_gName, array(
132 'email_greeting', 'postal_greeting', 'addressee'))) {
133 $defaults['contactOptions'] = (CRM_Utils_Array::value('filter', $defaults)) ? $defaults['filter'] : NULL;
134 }
135 // CRM-11516
136 if ($this->_gName == 'payment_instrument' && $this->_id) {
137 $defaults['financial_account_id'] = CRM_Financial_BAO_FinancialTypeAccount::getFinancialAccount($this->_id, 'civicrm_option_value', 'financial_account_id');
138 }
139 return $defaults;
140 }
141
142 /**
143 * Function to build the form
144 *
145 * @return None
146 * @access public
147 */
148 public function buildQuickForm() {
149 parent::buildQuickForm();
150 if ($this->_action & CRM_Core_Action::DELETE) {
151 return;
152 }
153
154 $this->applyFilter('__ALL__', 'trim');
155
156 $isReserved = FALSE;
157 if ($this->_id) {
158 $isReserved = (bool) CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionValue', $this->_id, 'is_reserved');
159 }
160
161 $this->add('text',
162 'label',
163 ts('Label'),
164 CRM_Core_DAO::getAttribute('CRM_Core_DAO_OptionValue', 'label'),
165 TRUE
166 );
167
168 if (!in_array($this->_gName, array(
169 'email_greeting', 'postal_greeting', 'addressee')) && !$isReserved) {
170 $this->addRule('label',
171 ts('This Label already exists in the database for this option group. Please select a different Value.'),
172 'optionExists',
173 array('CRM_Core_DAO_OptionValue', $this->_id, $this->_gid, 'label')
174 );
175 }
176
177 if ($this->_gName == 'case_status') {
178 $classes = array('Opened' => ts('Opened'),
179 'Closed' => ts('Closed'),
180 );
181
182 $grouping = $this->add('select',
183 'grouping',
184 ts('Status Class'),
185 $classes
186 );
187 if ($isReserved) {
188 $grouping->freeze();
189 }
190 }
191 // CRM-11516
192 if ($this->_gName == 'payment_instrument') {
193 $accountType = CRM_Core_PseudoConstant::accountOptionValues('financial_account_type', NULL, " AND v.name = 'Asset' ");
194 $financialAccount = CRM_Contribute_PseudoConstant::financialAccount(NULL, key($accountType));
195
196 $this->add('select', 'financial_account_id', ts('Financial Account'),
197 array('' => ts('- select -')) + $financialAccount
198 );
199 }
200
201 $required = FALSE;
202 if ($this->_gName == 'custom_search') {
203 $required = TRUE;
204 }
205 elseif ($this->_gName == 'redaction_rule' || $this->_gName == 'engagement_index') {
206 $this->add('text',
207 'value',
208 ts('Value'),
209 CRM_Core_DAO::getAttribute('CRM_Core_DAO_OptionValue', 'value'),
210 TRUE
211 );
212 if ($this->_gName == 'redaction_rule') {
213 $this->add('checkbox',
214 'filter',
215 ts('Regular Expression?')
216 );
217 }
218 }
219 if ($this->_gName == 'participant_listing') {
220 $this->add('text',
221 'description',
222 ts('Description'),
223 CRM_Core_DAO::getAttribute('CRM_Core_DAO_OptionValue', 'description')
224 );
225 }
226 else {
227 // Hard-coding attributes here since description is still stored as varchar and not text in the schema. dgg
228 $this->addWysiwyg('description',
229 ts('Description'),
230 array('rows' => 4, 'cols' => 80),
231 $required
232 );
233 }
234
235 if ($this->_gName == 'event_badge') {
236 $this->add('text',
237 'name',
238 ts('Class Name'),
239 CRM_Core_DAO::getAttribute('CRM_Core_DAO_OptionValue', 'name')
240 );
241 }
242
243 $this->add('text',
244 'weight',
245 ts('Weight'),
246 CRM_Core_DAO::getAttribute('CRM_Core_DAO_OptionValue', 'weight'),
247 TRUE
248 );
249 $this->addRule('weight', ts('is a numeric field'), 'numeric');
250
251 // If CiviCase enabled AND "Add" mode OR "edit" mode for non-reserved activities, only allow user to pick Core or CiviCase component.
252 // FIXME: Each component should define whether adding new activity types is allowed.
253 $config = CRM_Core_Config::singleton();
254 if ($this->_gName == 'activity_type' && in_array("CiviCase", $config->enableComponents) &&
255 (($this->_action & CRM_Core_Action::ADD) || !$isReserved)
256 ) {
257 $caseID = CRM_Core_Component::getComponentID('CiviCase');
258 $components = array('' => ts('Contacts OR Cases'), $caseID => ts('Cases Only'));
259 $this->add('select',
260 'component_id',
261 ts('Component'),
262 $components, FALSE
263 );
264 }
265
266 $enabled = $this->add('checkbox', 'is_active', ts('Enabled?'));
267
268 if ($isReserved) {
269 $enabled->freeze();
270 }
271
272 //fix for CRM-3552, CRM-4575
273 if (in_array($this->_gName, array(
274 'email_greeting', 'postal_greeting', 'addressee', 'from_email_address', 'case_status', 'encounter_medium', 'case_type', 'payment_instrument'))) {
275 $this->assign('showDefault', TRUE);
276 $this->add('checkbox', 'is_default', ts('Default Option?'));
277 }
278
279 //get contact type for which user want to create a new greeting/addressee type, CRM-4575
280 if (in_array($this->_gName, array(
281 'email_greeting', 'postal_greeting', 'addressee')) && !$isReserved) {
282 $values = array(1 => ts('Individual'),
283 2 => ts('Household'),
284 3 => ts('Organization'),
285 4 => ts('Multiple Contact Merge'),
286 );
287 $this->add('select', 'contactOptions', ts('Contact Type'), array('' => '-select-') + $values, TRUE);
288 $this->assign('showContactFilter', TRUE);
289 }
290
291 if ($this->_gName == 'participant_status') {
292 // For Participant Status options, expose the 'filter' field to track which statuses are "Counted", and the Visibility field
293 $element = $this->add('checkbox', 'filter', ts('Counted?'));
294 $this->add('select', 'visibility_id', ts('Visibility'), CRM_Core_PseudoConstant::visibility());
295 }
296 if ($this->_gName == 'participant_role') {
297 // For Participant Role options, expose the 'filter' field to track which statuses are "Counted"
298 $this->add('checkbox', 'filter', ts('Counted?'));
299 }
300
301 $this->addFormRule(array('CRM_Admin_Form_Options', 'formRule'), $this);
302 }
303
304 /**
305 * global form rule
306 *
307 * @param array $fields the input form values
308 * @param array $files the uploaded files if any
309 * @param array $self current form object.
310 *
311 * @return array array of errors / empty array.
312 * @access public
313 * @static
314 */
315 static function formRule($fields, $files, $self) {
316 $errors = array();
317 if ($self->_gName == 'case_status' && !CRM_Utils_Array::value('grouping', $fields)) {
318 $errors['grouping'] = ts('Status class is a required field');
319 }
320
321 if (in_array($self->_gName, array('email_greeting', 'postal_greeting', 'addressee'))
322 && !CRM_Utils_Array::value('is_reserved', $self->_defaultValues)
323 ) {
324 $label = $fields['label'];
325 $condition = " AND v.label = '{$label}' ";
326 $values = CRM_Core_OptionGroup::values($self->_gName, FALSE, FALSE, FALSE, $condition, 'filter');
327 $checkContactOptions = TRUE;
328
329 if ($self->_id && ($self->_defaultValues['contactOptions'] == $fields['contactOptions'])) {
330 $checkContactOptions = FALSE;
331 }
332
333 if ($checkContactOptions && in_array($fields['contactOptions'], $values)) {
334 $errors['label'] = ts('This Label already exists in the database for the selected contact type.');
335 }
336 }
337
338 if ($self->_gName == 'from_email_address') {
339 $formEmail = CRM_Utils_Mail::pluckEmailFromHeader($fields['label']);
340 if (!CRM_Utils_Rule::email($formEmail)) {
341 $errors['label'] = ts('Please enter the valid email address.');
342 }
343
344 $formName = explode('"', $fields['label']);
345 if (!CRM_Utils_Array::value(1, $formName) || count($formName) != 3) {
346 $errors['label'] = ts('Please follow the proper format for From Email Address');
347 }
348 }
349
350 return $errors;
351 }
352
353 /**
354 * Function to process the form
355 *
356 * @access public
357 *
358 * @return None
359 */
360 public function postProcess() {
361 if ($this->_action & CRM_Core_Action::DELETE) {
362 $fieldValues = array('option_group_id' => $this->_gid);
363 $wt = CRM_Utils_Weight::delWeight('CRM_Core_DAO_OptionValue', $this->_id, $fieldValues);
364
365 if (CRM_Core_BAO_OptionValue::del($this->_id)) {
366 if ($this->_gName == 'phone_type') {
367 CRM_Core_BAO_Phone::setOptionToNull(CRM_Utils_Array::value('value', $this->_defaultValues));
368 }
369
370 CRM_Core_Session::setStatus(ts('Selected %1 type has been deleted.', array(1 => $this->_GName)), ts('Record Deleted'), 'success');
371 }
372 else {
373 CRM_Core_Session::setStatus(ts('Selected %1 type has not been deleted.', array(1 => $this->_GName)), ts('Sorry'), 'error');
374 CRM_Utils_Weight::correctDuplicateWeights('CRM_Core_DAO_OptionValue', $fieldValues);
375 }
376 }
377 else {
378 $params = $ids = array();
379 $params = $this->exportValues();
380
381 // allow multiple defaults within group.
382 $allowMultiDefaults = array('email_greeting', 'postal_greeting', 'addressee', 'from_email_address');
383 if (in_array($this->_gName, $allowMultiDefaults)) {
384 if ($this->_gName == 'from_email_address') {
385 $params['reset_default_for'] = array('domain_id' => CRM_Core_Config::domainID());
386 }
387 elseif ($filter = CRM_Utils_Array::value('contactOptions', $params)) {
388 $params['filter'] = $filter;
389 $params['reset_default_for'] = array('filter' => "0, " . $params['filter']);
390 }
391
392 //make sure we should has to have space, CRM-6977
393 if ($this->_gName == 'from_email_address') {
394 $params['label'] = str_replace('"<', '" <', $params['label']);
395 }
396 }
397
398 // set db value of filter in params if filter is non editable
399 if ($this->_id && !array_key_exists('filter', $params) && !$this->_gName == 'participant_role') {
400 $params['filter'] = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionValue', $this->_id, 'filter', 'id');
401 }
402
403 $groupParams = array('name' => ($this->_gName));
404 $optionValue = CRM_Core_OptionValue::addOptionValue($params, $groupParams, $this->_action, $this->_id);
405
406 // CRM-11516
407 if (CRM_Utils_Array::value('financial_account_id', $params)) {
408 $relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Asset Account is' "));
409 $params = array(
410 'entity_table' => 'civicrm_option_value',
411 'entity_id' => $optionValue->id,
412 'account_relationship' => $relationTypeId,
413 'financial_account_id' => $params['financial_account_id']
414 );
415 CRM_Financial_BAO_FinancialTypeAccount::add($params);
416 }
417
418 CRM_Core_Session::setStatus(ts('The %1 \'%2\' has been saved.', array(1 => $this->_GName, 2 => $optionValue->label)), ts('Saved'), 'success');
419 }
420 }
421 }