/administrator/components/com_contact/models/contact.php
PHP | 521 lines | 290 code | 71 blank | 160 comment | 43 complexity | 4b5fad2f663c05f76da1cfdb1a27a876 MD5 | raw file
Possible License(s): LGPL-2.1
1<?php 2/** 3 * @package Joomla.Administrator 4 * @subpackage com_contact 5 * 6 * @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved. 7 * @license GNU General Public License version 2 or later; see LICENSE.txt 8 */ 9 10defined('_JEXEC') or die; 11 12/** 13 * Item Model for a Contact. 14 * 15 * @package Joomla.Administrator 16 * @subpackage com_contact 17 * @since 1.6 18 */ 19class ContactModelContact extends JModelAdmin 20{ 21 /** 22 * Method to perform batch operations on an item or a set of items. 23 * 24 * @param array $commands An array of commands to perform. 25 * @param array $pks An array of item ids. 26 * @param array $contexts An array of item contexts. 27 * 28 * @return boolean Returns true on success, false on failure. 29 * 30 * @since 2.5 31 */ 32 public function batch($commands, $pks, $contexts) 33 { 34 // Sanitize user ids. 35 $pks = array_unique($pks); 36 JArrayHelper::toInteger($pks); 37 38 // Remove any values of zero. 39 if (array_search(0, $pks, true)) 40 { 41 unset($pks[array_search(0, $pks, true)]); 42 } 43 44 if (empty($pks)) 45 { 46 $this->setError(JText::_('JGLOBAL_NO_ITEM_SELECTED')); 47 return false; 48 } 49 50 $done = false; 51 52 if (!empty($commands['category_id'])) 53 { 54 $cmd = JArrayHelper::getValue($commands, 'move_copy', 'c'); 55 56 if ($cmd == 'c') 57 { 58 $result = $this->batchCopy($commands['category_id'], $pks, $contexts); 59 if (is_array($result)) 60 { 61 $pks = $result; 62 } 63 else 64 { 65 return false; 66 } 67 } 68 elseif ($cmd == 'm' && !$this->batchMove($commands['category_id'], $pks, $contexts)) 69 { 70 return false; 71 } 72 $done = true; 73 } 74 75 if (!empty($commands['assetgroup_id'])) 76 { 77 if (!$this->batchAccess($commands['assetgroup_id'], $pks, $contexts)) 78 { 79 return false; 80 } 81 82 $done = true; 83 } 84 85 if (!empty($commands['language_id'])) 86 { 87 if (!$this->batchLanguage($commands['language_id'], $pks, $contexts)) 88 { 89 return false; 90 } 91 92 $done = true; 93 } 94 95 if (strlen($commands['user_id']) > 0) 96 { 97 if (!$this->batchUser($commands['user_id'], $pks, $contexts)) 98 { 99 return false; 100 } 101 102 $done = true; 103 } 104 105 if (!$done) 106 { 107 $this->setError(JText::_('JLIB_APPLICATION_ERROR_INSUFFICIENT_BATCH_INFORMATION')); 108 return false; 109 } 110 111 // Clear the cache 112 $this->cleanCache(); 113 114 return true; 115 } 116 117 /** 118 * Batch copy items to a new category or current. 119 * 120 * @param integer $value The new category. 121 * @param array $pks An array of row IDs. 122 * @param array $contexts An array of item contexts. 123 * 124 * @return mixed An array of new IDs on success, boolean false on failure. 125 * 126 * @since 11.1 127 */ 128 protected function batchCopy($value, $pks, $contexts) 129 { 130 $categoryId = (int) $value; 131 132 $table = $this->getTable(); 133 $i = 0; 134 135 // Check that the category exists 136 if ($categoryId) 137 { 138 $categoryTable = JTable::getInstance('Category'); 139 if (!$categoryTable->load($categoryId)) 140 { 141 if ($error = $categoryTable->getError()) 142 { 143 // Fatal error 144 $this->setError($error); 145 return false; 146 } 147 else 148 { 149 $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_MOVE_CATEGORY_NOT_FOUND')); 150 return false; 151 } 152 } 153 } 154 155 if (empty($categoryId)) 156 { 157 $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_MOVE_CATEGORY_NOT_FOUND')); 158 return false; 159 } 160 161 // Check that the user has create permission for the component 162 $user = JFactory::getUser(); 163 if (!$user->authorise('core.create', 'com_contact.category.' . $categoryId)) 164 { 165 $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_CREATE')); 166 return false; 167 } 168 169 // Parent exists so we let's proceed 170 while (!empty($pks)) 171 { 172 // Pop the first ID off the stack 173 $pk = array_shift($pks); 174 175 $table->reset(); 176 177 // Check that the row actually exists 178 if (!$table->load($pk)) 179 { 180 if ($error = $table->getError()) 181 { 182 // Fatal error 183 $this->setError($error); 184 return false; 185 } 186 else 187 { 188 // Not fatal error 189 $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_BATCH_MOVE_ROW_NOT_FOUND', $pk)); 190 continue; 191 } 192 } 193 194 // Alter the title & alias 195 $data = $this->generateNewTitle($categoryId, $table->alias, $table->name); 196 $table->name = $data['0']; 197 $table->alias = $data['1']; 198 199 // Reset the ID because we are making a copy 200 $table->id = 0; 201 202 // New category ID 203 $table->catid = $categoryId; 204 205 // TODO: Deal with ordering? 206 //$table->ordering = 1; 207 208 // Check the row. 209 if (!$table->check()) 210 { 211 $this->setError($table->getError()); 212 return false; 213 } 214 215 // Store the row. 216 if (!$table->store()) 217 { 218 $this->setError($table->getError()); 219 return false; 220 } 221 222 // Get the new item ID 223 $newId = $table->get('id'); 224 225 // Add the new ID to the array 226 $newIds[$i] = $newId; 227 $i++; 228 } 229 230 // Clean the cache 231 $this->cleanCache(); 232 233 return $newIds; 234 } 235 236 /** 237 * Batch change a linked user. 238 * 239 * @param integer $value The new value matching a User ID. 240 * @param array $pks An array of row IDs. 241 * @param array $contexts An array of item contexts. 242 * 243 * @return boolean True if successful, false otherwise and internal error is set. 244 * 245 * @since 2.5 246 */ 247 protected function batchUser($value, $pks, $contexts) 248 { 249 // Set the variables 250 $user = JFactory::getUser(); 251 $table = $this->getTable(); 252 253 foreach ($pks as $pk) 254 { 255 if ($user->authorise('core.edit', $contexts[$pk])) 256 { 257 $table->reset(); 258 $table->load($pk); 259 $table->user_id = (int) $value; 260 261 if (!$table->store()) 262 { 263 $this->setError($table->getError()); 264 return false; 265 } 266 } 267 else 268 { 269 $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT')); 270 return false; 271 } 272 } 273 274 // Clean the cache 275 $this->cleanCache(); 276 277 return true; 278 } 279 280 /** 281 * Method to test whether a record can be deleted. 282 * 283 * @param object $record A record object. 284 * 285 * @return boolean True if allowed to delete the record. Defaults to the permission set in the component. 286 * @since 1.6 287 */ 288 protected function canDelete($record) 289 { 290 if (!empty($record->id)) { 291 if ($record->published != -2) { 292 return; 293 } 294 $user = JFactory::getUser(); 295 return $user->authorise('core.delete', 'com_contact.category.'.(int) $record->catid); 296 } 297 } 298 299 /** 300 * Method to test whether a record can have its state edited. 301 * 302 * @param object $record A record object. 303 * 304 * @return boolean True if allowed to change the state of the record. Defaults to the permission set in the component. 305 * @since 1.6 306 */ 307 protected function canEditState($record) 308 { 309 $user = JFactory::getUser(); 310 311 // Check against the category. 312 if (!empty($record->catid)) { 313 return $user->authorise('core.edit.state', 'com_contact.category.'.(int) $record->catid); 314 } 315 // Default to component settings if category not known. 316 else { 317 return parent::canEditState($record); 318 } 319 } 320 321 /** 322 * Returns a Table object, always creating it 323 * 324 * @param type $type The table type to instantiate 325 * @param string $prefix A prefix for the table class name. Optional. 326 * @param array $config Configuration array for model. Optional. 327 * 328 * @return JTable A database object 329 * @since 1.6 330 */ 331 public function getTable($type = 'Contact', $prefix = 'ContactTable', $config = array()) 332 { 333 return JTable::getInstance($type, $prefix, $config); 334 } 335 336 /** 337 * Method to get the row form. 338 * 339 * @param array $data Data for the form. 340 * @param boolean $loadData True if the form is to load its own data (default case), false if not. 341 * 342 * @return mixed A JForm object on success, false on failure 343 * @since 1.6 344 */ 345 public function getForm($data = array(), $loadData = true) 346 { 347 JForm::addFieldPath('JPATH_ADMINISTRATOR/components/com_users/models/fields'); 348 349 // Get the form. 350 $form = $this->loadForm('com_contact.contact', 'contact', array('control' => 'jform', 'load_data' => $loadData)); 351 if (empty($form)) { 352 return false; 353 } 354 355 // Modify the form based on access controls. 356 if (!$this->canEditState((object) $data)) { 357 // Disable fields for display. 358 $form->setFieldAttribute('featured', 'disabled', 'true'); 359 $form->setFieldAttribute('ordering', 'disabled', 'true'); 360 $form->setFieldAttribute('published', 'disabled', 'true'); 361 362 // Disable fields while saving. 363 // The controller has already verified this is a record you can edit. 364 $form->setFieldAttribute('featured', 'filter', 'unset'); 365 $form->setFieldAttribute('ordering', 'filter', 'unset'); 366 $form->setFieldAttribute('published', 'filter', 'unset'); 367 } 368 369 return $form; 370 } 371 372 /** 373 * Method to get a single record. 374 * 375 * @param integer $pk The id of the primary key. 376 * 377 * @return mixed Object on success, false on failure. 378 * @since 1.6 379 */ 380 public function getItem($pk = null) 381 { 382 if ($item = parent::getItem($pk)) { 383 // Convert the params field to an array. 384 $registry = new JRegistry; 385 $registry->loadString($item->metadata); 386 $item->metadata = $registry->toArray(); 387 } 388 389 return $item; 390 } 391 392 /** 393 * Method to get the data that should be injected in the form. 394 * 395 * @return mixed The data for the form. 396 * @since 1.6 397 */ 398 protected function loadFormData() 399 { 400 // Check the session for previously entered form data. 401 $data = JFactory::getApplication()->getUserState('com_contact.edit.contact.data', array()); 402 403 if (empty($data)) { 404 $data = $this->getItem(); 405 406 // Prime some default values. 407 if ($this->getState('contact.id') == 0) { 408 $app = JFactory::getApplication(); 409 $data->set('catid', $app->input->get('catid', $app->getUserState('com_contact.contacts.filter.category_id'), 'int')); 410 } 411 } 412 413 return $data; 414 } 415 416 /** 417 * Prepare and sanitise the table prior to saving. 418 * 419 * @param JTable $table 420 * 421 * @return void 422 * @since 1.6 423 */ 424 protected function prepareTable($table) 425 { 426 $date = JFactory::getDate(); 427 $user = JFactory::getUser(); 428 429 $table->name = htmlspecialchars_decode($table->name, ENT_QUOTES); 430 $table->alias = JApplication::stringURLSafe($table->alias); 431 432 if (empty($table->alias)) { 433 $table->alias = JApplication::stringURLSafe($table->name); 434 } 435 436 if (empty($table->id)) { 437 // Set the values 438 $table->created = $date->toSql(); 439 440 // Set ordering to the last item if not set 441 if (empty($table->ordering)) { 442 $db = JFactory::getDbo(); 443 $db->setQuery('SELECT MAX(ordering) FROM #__contact_details'); 444 $max = $db->loadResult(); 445 446 $table->ordering = $max + 1; 447 } 448 } 449 else { 450 // Set the values 451 $table->modified = $date->toSql(); 452 $table->modified_by = $user->get('id'); 453 } 454 // Increment the content version number. 455 $table->version++; 456 457 } 458 459 /** 460 * A protected method to get a set of ordering conditions. 461 * 462 * @param JTable $table A record object. 463 * 464 * @return array An array of conditions to add to add to ordering queries. 465 * @since 1.6 466 */ 467 protected function getReorderConditions($table) 468 { 469 $condition = array(); 470 $condition[] = 'catid = '.(int) $table->catid; 471 472 return $condition; 473 } 474 475 /** 476 * Method to toggle the featured setting of contacts. 477 * 478 * @param array $pks The ids of the items to toggle. 479 * @param int $value The value to toggle to. 480 * 481 * @return boolean True on success. 482 * @since 1.6 483 */ 484 public function featured($pks, $value = 0) 485 { 486 // Sanitize the ids. 487 $pks = (array) $pks; 488 JArrayHelper::toInteger($pks); 489 490 if (empty($pks)) { 491 $this->setError(JText::_('COM_CONTACT_NO_ITEM_SELECTED')); 492 return false; 493 } 494 495 $table = $this->getTable(); 496 497 try 498 { 499 $db = $this->getDbo(); 500 501 $db->setQuery( 502 'UPDATE #__contact_details' . 503 ' SET featured = '.(int) $value. 504 ' WHERE id IN ('.implode(',', $pks).')' 505 ); 506 $db->execute(); 507 } 508 catch (Exception $e) 509 { 510 $this->setError($e->getMessage()); 511 return false; 512 } 513 514 $table->reorder(); 515 516 // Clean component's cache 517 $this->cleanCache(); 518 519 return true; 520 } 521}