PageRenderTime 54ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

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

https://github.com/J2MTecnologia/joomla-3.x
PHP | 754 lines | 449 code | 113 blank | 192 comment | 64 complexity | b44f37e9569ff9a8a82f62042055026a MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, BSD-3-Clause
  1. <?php
  2. /**
  3. * @package Joomla.Administrator
  4. * @subpackage com_contact
  5. *
  6. * @copyright Copyright (C) 2005 - 2014 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. JLoader::register('ContactHelper', JPATH_ADMINISTRATOR . '/components/com_contact/helpers/contact.php');
  11. /**
  12. * Item Model for a Contact.
  13. *
  14. * @package Joomla.Administrator
  15. * @subpackage com_contact
  16. * @since 1.6
  17. */
  18. class ContactModelContact extends JModelAdmin
  19. {
  20. /**
  21. * The type alias for this content type.
  22. *
  23. * @var string
  24. * @since 3.2
  25. */
  26. public $typeAlias = 'com_contact.contact';
  27. /**
  28. * Method to perform batch operations on an item or a set of items.
  29. *
  30. * @param array $commands An array of commands to perform.
  31. * @param array $pks An array of item ids.
  32. * @param array $contexts An array of item contexts.
  33. *
  34. * @return boolean Returns true on success, false on failure.
  35. *
  36. * @since 2.5
  37. */
  38. public function batch($commands, $pks, $contexts)
  39. {
  40. // Sanitize user ids.
  41. $pks = array_unique($pks);
  42. JArrayHelper::toInteger($pks);
  43. // Remove any values of zero.
  44. if (array_search(0, $pks, true))
  45. {
  46. unset($pks[array_search(0, $pks, true)]);
  47. }
  48. if (empty($pks))
  49. {
  50. $this->setError(JText::_('JGLOBAL_NO_ITEM_SELECTED'));
  51. return false;
  52. }
  53. $done = false;
  54. // Set some needed variables.
  55. $this->user = JFactory::getUser();
  56. $this->table = $this->getTable();
  57. $this->tableClassName = get_class($this->table);
  58. $this->contentType = new JUcmType;
  59. $this->type = $this->contentType->getTypeByTable($this->tableClassName);
  60. $this->batchSet = true;
  61. if ($this->type === false)
  62. {
  63. $type = new JUcmType;
  64. $this->type = $type->getTypeByAlias($this->typeAlias);
  65. $typeAlias = $this->type->type_alias;
  66. }
  67. else
  68. {
  69. $typeAlias = $this->type->type_alias;
  70. }
  71. $this->tagsObserver = $this->table->getObserverOfClass('JTableObserverTags');
  72. if (!empty($commands['category_id']))
  73. {
  74. $cmd = JArrayHelper::getValue($commands, 'move_copy', 'c');
  75. if ($cmd == 'c')
  76. {
  77. $result = $this->batchCopy($commands['category_id'], $pks, $contexts);
  78. if (is_array($result))
  79. {
  80. $pks = $result;
  81. }
  82. else
  83. {
  84. return false;
  85. }
  86. }
  87. elseif ($cmd == 'm' && !$this->batchMove($commands['category_id'], $pks, $contexts))
  88. {
  89. return false;
  90. }
  91. $done = true;
  92. }
  93. if (!empty($commands['assetgroup_id']))
  94. {
  95. if (!$this->batchAccess($commands['assetgroup_id'], $pks, $contexts))
  96. {
  97. return false;
  98. }
  99. $done = true;
  100. }
  101. if (!empty($commands['language_id']))
  102. {
  103. if (!$this->batchLanguage($commands['language_id'], $pks, $contexts))
  104. {
  105. return false;
  106. }
  107. $done = true;
  108. }
  109. if (!empty($commands['tag']))
  110. {
  111. if (!$this->batchTag($commands['tag'], $pks, $contexts))
  112. {
  113. return false;
  114. }
  115. $done = true;
  116. }
  117. if (strlen($commands['user_id']) > 0)
  118. {
  119. if (!$this->batchUser($commands['user_id'], $pks, $contexts))
  120. {
  121. return false;
  122. }
  123. $done = true;
  124. }
  125. if (!$done)
  126. {
  127. $this->setError(JText::_('JLIB_APPLICATION_ERROR_INSUFFICIENT_BATCH_INFORMATION'));
  128. return false;
  129. }
  130. // Clear the cache
  131. $this->cleanCache();
  132. return true;
  133. }
  134. /**
  135. * Batch copy items to a new category or current.
  136. *
  137. * @param integer $value The new category.
  138. * @param array $pks An array of row IDs.
  139. * @param array $contexts An array of item contexts.
  140. *
  141. * @return mixed An array of new IDs on success, boolean false on failure.
  142. *
  143. * @since 11.1
  144. */
  145. protected function batchCopy($value, $pks, $contexts)
  146. {
  147. $categoryId = (int) $value;
  148. $table = $this->getTable();
  149. $i = 0;
  150. if (!parent::checkCategoryId($categoryId))
  151. {
  152. return false;
  153. }
  154. // Parent exists so we proceed
  155. while (!empty($pks))
  156. {
  157. // Pop the first ID off the stack
  158. $pk = array_shift($pks);
  159. $this->table->reset();
  160. // Check that the row actually exists
  161. if (!$this->table->load($pk))
  162. {
  163. if ($error = $this->table->getError())
  164. {
  165. // Fatal error
  166. $this->setError($error);
  167. return false;
  168. }
  169. else
  170. {
  171. // Not fatal error
  172. $this->setError(JText::sprintf('JLIB_APPLICATION_ERROR_BATCH_MOVE_ROW_NOT_FOUND', $pk));
  173. continue;
  174. }
  175. }
  176. // Alter the title & alias
  177. $data = $this->generateNewTitle($categoryId, $this->table->alias, $this->table->name);
  178. $this->table->name = $data['0'];
  179. $this->table->alias = $data['1'];
  180. // Reset the ID because we are making a copy
  181. $this->table->id = 0;
  182. // New category ID
  183. $this->table->catid = $categoryId;
  184. // TODO: Deal with ordering?
  185. //$this->table->ordering = 1;
  186. // Check the row.
  187. if (!$this->table->check())
  188. {
  189. $this->setError($this->table->getError());
  190. return false;
  191. }
  192. parent::createTagsHelper($this->tagsObserver, $this->type, $pk, $this->typeAlias, $this->table);
  193. // Store the row.
  194. if (!$this->table->store())
  195. {
  196. $this->setError($this->table->getError());
  197. return false;
  198. }
  199. // Get the new item ID
  200. $newId = $this->table->get('id');
  201. // Add the new ID to the array
  202. $newIds[$i] = $newId;
  203. $i++;
  204. }
  205. // Clean the cache
  206. $this->cleanCache();
  207. return $newIds;
  208. }
  209. /**
  210. * Batch change a linked user.
  211. *
  212. * @param integer $value The new value matching a User ID.
  213. * @param array $pks An array of row IDs.
  214. * @param array $contexts An array of item contexts.
  215. *
  216. * @return boolean True if successful, false otherwise and internal error is set.
  217. *
  218. * @since 2.5
  219. */
  220. protected function batchUser($value, $pks, $contexts)
  221. {
  222. foreach ($pks as $pk)
  223. {
  224. if ($this->user->authorise('core.edit', $contexts[$pk]))
  225. {
  226. $this->table->reset();
  227. $this->table->load($pk);
  228. $this->table->user_id = (int) $value;
  229. static::createTagsHelper($this->tagsObserver, $this->type, $pk, $this->typeAlias, $this->table);
  230. if (!$this->table->store())
  231. {
  232. $this->this->setError($table->getError());
  233. return false;
  234. }
  235. }
  236. else
  237. {
  238. $this->setError(JText::_('JLIB_APPLICATION_ERROR_BATCH_CANNOT_EDIT'));
  239. return false;
  240. }
  241. }
  242. // Clean the cache
  243. $this->cleanCache();
  244. return true;
  245. }
  246. /**
  247. * Method to test whether a record can be deleted.
  248. *
  249. * @param object $record A record object.
  250. *
  251. * @return boolean True if allowed to delete the record. Defaults to the permission set in the component.
  252. * @since 1.6
  253. */
  254. protected function canDelete($record)
  255. {
  256. if (!empty($record->id))
  257. {
  258. if ($record->published != -2)
  259. {
  260. return;
  261. }
  262. $user = JFactory::getUser();
  263. return $user->authorise('core.delete', 'com_contact.category.' . (int) $record->catid);
  264. }
  265. }
  266. /**
  267. * Method to test whether a record can have its state edited.
  268. *
  269. * @param object $record A record object.
  270. *
  271. * @return boolean True if allowed to change the state of the record. Defaults to the permission set in the component.
  272. * @since 1.6
  273. */
  274. protected function canEditState($record)
  275. {
  276. $user = JFactory::getUser();
  277. // Check against the category.
  278. if (!empty($record->catid))
  279. {
  280. return $user->authorise('core.edit.state', 'com_contact.category.' . (int) $record->catid);
  281. }
  282. // Default to component settings if category not known.
  283. else
  284. {
  285. return parent::canEditState($record);
  286. }
  287. }
  288. /**
  289. * Returns a Table object, always creating it
  290. *
  291. * @param type $type The table type to instantiate
  292. * @param string $prefix A prefix for the table class name. Optional.
  293. * @param array $config Configuration array for model. Optional.
  294. *
  295. * @return JTable A database object
  296. * @since 1.6
  297. */
  298. public function getTable($type = 'Contact', $prefix = 'ContactTable', $config = array())
  299. {
  300. return JTable::getInstance($type, $prefix, $config);
  301. }
  302. /**
  303. * Method to get the row form.
  304. *
  305. * @param array $data Data for the form.
  306. * @param boolean $loadData True if the form is to load its own data (default case), false if not.
  307. *
  308. * @return mixed A JForm object on success, false on failure
  309. * @since 1.6
  310. */
  311. public function getForm($data = array(), $loadData = true)
  312. {
  313. JForm::addFieldPath('JPATH_ADMINISTRATOR/components/com_users/models/fields');
  314. // Get the form.
  315. $form = $this->loadForm('com_contact.contact', 'contact', array('control' => 'jform', 'load_data' => $loadData));
  316. if (empty($form))
  317. {
  318. return false;
  319. }
  320. // Modify the form based on access controls.
  321. if (!$this->canEditState((object) $data))
  322. {
  323. // Disable fields for display.
  324. $form->setFieldAttribute('featured', 'disabled', 'true');
  325. $form->setFieldAttribute('ordering', 'disabled', 'true');
  326. $form->setFieldAttribute('published', 'disabled', 'true');
  327. // Disable fields while saving.
  328. // The controller has already verified this is a record you can edit.
  329. $form->setFieldAttribute('featured', 'filter', 'unset');
  330. $form->setFieldAttribute('ordering', 'filter', 'unset');
  331. $form->setFieldAttribute('published', 'filter', 'unset');
  332. }
  333. return $form;
  334. }
  335. /**
  336. * Method to get a single record.
  337. *
  338. * @param integer $pk The id of the primary key.
  339. *
  340. * @return mixed Object on success, false on failure.
  341. * @since 1.6
  342. */
  343. public function getItem($pk = null)
  344. {
  345. if ($item = parent::getItem($pk))
  346. {
  347. // Convert the metadata field to an array.
  348. $registry = new JRegistry;
  349. $registry->loadString($item->metadata);
  350. $item->metadata = $registry->toArray();
  351. }
  352. // Load associated contact items
  353. $app = JFactory::getApplication();
  354. $assoc = JLanguageAssociations::isEnabled();
  355. if ($assoc)
  356. {
  357. $item->associations = array();
  358. if ($item->id != null)
  359. {
  360. $associations = JLanguageAssociations::getAssociations('com_contact', '#__contact_details', 'com_contact.item', $item->id);
  361. foreach ($associations as $tag => $association)
  362. {
  363. $item->associations[$tag] = $association->id;
  364. }
  365. }
  366. }
  367. // Load item tags
  368. if (!empty($item->id))
  369. {
  370. $item->tags = new JHelperTags;
  371. $item->tags->getTagIds($item->id, 'com_contact.contact');
  372. }
  373. return $item;
  374. }
  375. /**
  376. * Method to get the data that should be injected in the form.
  377. *
  378. * @return mixed The data for the form.
  379. * @since 1.6
  380. */
  381. protected function loadFormData()
  382. {
  383. // Check the session for previously entered form data.
  384. $data = JFactory::getApplication()->getUserState('com_contact.edit.contact.data', array());
  385. if (empty($data))
  386. {
  387. $data = $this->getItem();
  388. // Prime some default values.
  389. if ($this->getState('contact.id') == 0)
  390. {
  391. $app = JFactory::getApplication();
  392. $data->set('catid', $app->input->get('catid', $app->getUserState('com_contact.contacts.filter.category_id'), 'int'));
  393. }
  394. }
  395. $this->preprocessData('com_contact.contact', $data);
  396. return $data;
  397. }
  398. /**
  399. * Method to save the form data.
  400. *
  401. * @param array The form data.
  402. *
  403. * @return boolean True on success.
  404. * @since 3.0
  405. */
  406. public function save($data)
  407. {
  408. $app = JFactory::getApplication();
  409. // Alter the title for save as copy
  410. if ($app->input->get('task') == 'save2copy')
  411. {
  412. list($name, $alias) = $this->generateNewTitle($data['catid'], $data['alias'], $data['name']);
  413. $data['name'] = $name;
  414. $data['alias'] = $alias;
  415. $data['published'] = 0;
  416. }
  417. $links = array('linka', 'linkb', 'linkc', 'linkd', 'linke');
  418. foreach ($links as $link)
  419. {
  420. if ($data['params'][$link])
  421. {
  422. $data['params'][$link] = JStringPunycode::urlToPunycode($data['params'][$link]);
  423. }
  424. }
  425. if (parent::save($data))
  426. {
  427. $assoc = JLanguageAssociations::isEnabled();
  428. if ($assoc)
  429. {
  430. $id = (int) $this->getState($this->getName() . '.id');
  431. $item = $this->getItem($id);
  432. // Adding self to the association
  433. $associations = $data['associations'];
  434. foreach ($associations as $tag => $id)
  435. {
  436. if (empty($id))
  437. {
  438. unset($associations[$tag]);
  439. }
  440. }
  441. // Detecting all item menus
  442. $all_language = $item->language == '*';
  443. if ($all_language && !empty($associations))
  444. {
  445. JError::raiseNotice(403, JText::_('COM_CONTACT_ERROR_ALL_LANGUAGE_ASSOCIATED'));
  446. }
  447. $associations[$item->language] = $item->id;
  448. // Deleting old association for these items
  449. $db = JFactory::getDbo();
  450. $query = $db->getQuery(true)
  451. ->delete('#__associations')
  452. ->where('context=' . $db->quote('com_contact.item'))
  453. ->where('id IN (' . implode(',', $associations) . ')');
  454. $db->setQuery($query);
  455. $db->execute();
  456. if ($error = $db->getErrorMsg())
  457. {
  458. $this->setError($error);
  459. return false;
  460. }
  461. if (!$all_language && count($associations))
  462. {
  463. // Adding new association for these items
  464. $key = md5(json_encode($associations));
  465. $query->clear()
  466. ->insert('#__associations');
  467. foreach ($associations as $id)
  468. {
  469. $query->values($id . ',' . $db->quote('com_contact.item') . ',' . $db->quote($key));
  470. }
  471. $db->setQuery($query);
  472. $db->execute();
  473. if ($error = $db->getErrorMsg())
  474. {
  475. $this->setError($error);
  476. return false;
  477. }
  478. }
  479. }
  480. return true;
  481. }
  482. return false;
  483. }
  484. /**
  485. * Prepare and sanitise the table prior to saving.
  486. *
  487. * @param JTable $table
  488. *
  489. * @return void
  490. * @since 1.6
  491. */
  492. protected function prepareTable($table)
  493. {
  494. $date = JFactory::getDate();
  495. $user = JFactory::getUser();
  496. $table->name = htmlspecialchars_decode($table->name, ENT_QUOTES);
  497. $table->generateAlias();
  498. if (empty($table->id))
  499. {
  500. // Set the values
  501. $table->created = $date->toSql();
  502. // Set ordering to the last item if not set
  503. if (empty($table->ordering))
  504. {
  505. $db = JFactory::getDbo();
  506. $query = $db->getQuery(true)
  507. ->select('MAX(ordering)')
  508. ->from($db->quoteName('#__contact_details'));
  509. $db->setQuery($query);
  510. $max = $db->loadResult();
  511. $table->ordering = $max + 1;
  512. }
  513. }
  514. else
  515. {
  516. // Set the values
  517. $table->modified = $date->toSql();
  518. $table->modified_by = $user->get('id');
  519. }
  520. // Increment the content version number.
  521. $table->version++;
  522. }
  523. /**
  524. * A protected method to get a set of ordering conditions.
  525. *
  526. * @param JTable $table A record object.
  527. *
  528. * @return array An array of conditions to add to add to ordering queries.
  529. * @since 1.6
  530. */
  531. protected function getReorderConditions($table)
  532. {
  533. $condition = array();
  534. $condition[] = 'catid = ' . (int) $table->catid;
  535. return $condition;
  536. }
  537. protected function preprocessForm(JForm $form, $data, $group = 'content')
  538. {
  539. // Association content items
  540. $app = JFactory::getApplication();
  541. $assoc = JLanguageAssociations::isEnabled();
  542. if ($assoc)
  543. {
  544. $languages = JLanguageHelper::getLanguages('lang_code');
  545. // force to array (perhaps move to $this->loadFormData())
  546. $data = (array) $data;
  547. $addform = new SimpleXMLElement('<form />');
  548. $fields = $addform->addChild('fields');
  549. $fields->addAttribute('name', 'associations');
  550. $fieldset = $fields->addChild('fieldset');
  551. $fieldset->addAttribute('name', 'item_associations');
  552. $fieldset->addAttribute('description', 'COM_CONTACT_ITEM_ASSOCIATIONS_FIELDSET_DESC');
  553. $add = false;
  554. foreach ($languages as $tag => $language)
  555. {
  556. if (empty($data['language']) || $tag != $data['language'])
  557. {
  558. $add = true;
  559. $field = $fieldset->addChild('field');
  560. $field->addAttribute('name', $tag);
  561. $field->addAttribute('type', 'modal_contact');
  562. $field->addAttribute('language', $tag);
  563. $field->addAttribute('label', $language->title);
  564. $field->addAttribute('translate_label', 'false');
  565. $field->addAttribute('edit', 'true');
  566. $field->addAttribute('clear', 'true');
  567. }
  568. }
  569. if ($add)
  570. {
  571. $form->load($addform, false);
  572. }
  573. }
  574. parent::preprocessForm($form, $data, $group);
  575. }
  576. /**
  577. * Method to toggle the featured setting of contacts.
  578. *
  579. * @param array $pks The ids of the items to toggle.
  580. * @param integer $value The value to toggle to.
  581. *
  582. * @return boolean True on success.
  583. * @since 1.6
  584. */
  585. public function featured($pks, $value = 0)
  586. {
  587. // Sanitize the ids.
  588. $pks = (array) $pks;
  589. JArrayHelper::toInteger($pks);
  590. if (empty($pks))
  591. {
  592. $this->setError(JText::_('COM_CONTACT_NO_ITEM_SELECTED'));
  593. return false;
  594. }
  595. $table = $this->getTable();
  596. try
  597. {
  598. $db = $this->getDbo();
  599. $query = $db->getQuery(true);
  600. $query->update('#__contact_details');
  601. $query->set('featured = ' . (int) $value);
  602. $query->where('id IN (' . implode(',', $pks) . ')');
  603. $db->setQuery($query);
  604. $db->execute();
  605. }
  606. catch (Exception $e)
  607. {
  608. $this->setError($e->getMessage());
  609. return false;
  610. }
  611. $table->reorder();
  612. // Clean component's cache
  613. $this->cleanCache();
  614. return true;
  615. }
  616. /**
  617. * Method to change the title & alias.
  618. *
  619. * @param integer $parent_id The id of the parent.
  620. * @param string $alias The alias.
  621. * @param string $title The title.
  622. *
  623. * @return array Contains the modified title and alias.
  624. *
  625. * @since 3.1
  626. */
  627. protected function generateNewTitle($category_id, $alias, $name)
  628. {
  629. // Alter the title & alias
  630. $table = $this->getTable();
  631. while ($table->load(array('alias' => $alias, 'catid' => $category_id)))
  632. {
  633. if ($name == $table->name)
  634. {
  635. $name = JString::increment($name);
  636. }
  637. $alias = JString::increment($alias, 'dash');
  638. }
  639. return array($name, $alias);
  640. }
  641. }