/administrator/components/com_contact/models/contact.php

https://bitbucket.org/eternaware/joomus · PHP · 521 lines · 290 code · 71 blank · 160 comment · 43 complexity · 4b5fad2f663c05f76da1cfdb1a27a876 MD5 · raw file

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