Source for file users.php

Documentation is available at users.php

  1. <?php
  2. /**
  3.  * @package     Joomla.Administrator
  4.  * @subpackage  com_users
  5.  *
  6.  * @copyright   Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
  7.  * @license     GNU General Public License version 2 or later; see LICENSE.txt
  8.  */
  9.  
  10. defined('_JEXEC'or die;
  11.  
  12. /**
  13.  * Methods supporting a list of user records.
  14.  *
  15.  * @package     Joomla.Administrator
  16.  * @subpackage  com_users
  17.  * @since       1.6
  18.  */
  19. class UsersModelUsers extends JModelList
  20. {
  21.     /**
  22.      * Constructor.
  23.      *
  24.      * @param   array  $config  An optional associative array of configuration settings.
  25.      *
  26.      * @see     JController
  27.      * @since   1.6
  28.      */
  29.     public function __construct($config array())
  30.     {
  31.         if (empty($config['filter_fields']))
  32.         {
  33.             $config['filter_fields'array(
  34.                 'id''a.id',
  35.                 'name''a.name',
  36.                 'username''a.username',
  37.                 'email''a.email',
  38.                 'block''a.block',
  39.                 'sendEmail''a.sendEmail',
  40.                 'registerDate''a.registerDate',
  41.                 'lastvisitDate''a.lastvisitDate',
  42.                 'activation''a.activation',
  43.                 'active',
  44.                 'group_id',
  45.                 'range',
  46.                 'state',
  47.             );
  48.         }
  49.  
  50.         parent::__construct($config);
  51.     }
  52.  
  53.     /**
  54.      * Method to auto-populate the model state.
  55.      *
  56.      * Note. Calling getState in this method will result in recursion.
  57.      *
  58.      * @param   string  $ordering   An optional ordering field.
  59.      * @param   string  $direction  An optional direction (asc|desc).
  60.      *
  61.      * @return  void 
  62.      *
  63.      * @since   1.6
  64.      */
  65.     protected function populateState($ordering null$direction null)
  66.     {
  67.         $app JFactory::getApplication('administrator');
  68.  
  69.         // Adjust the context to support modal layouts.
  70.         if ($layout $app->input->get('layout''default''cmd'))
  71.         {
  72.             $this->context .= '.' $layout;
  73.         }
  74.  
  75.         // Load the filter state.
  76.         $search $this->getUserStateFromRequest($this->context . '.filter.search''filter_search');
  77.         $this->setState('filter.search'$search);
  78.  
  79.         $active $this->getUserStateFromRequest($this->context . '.filter.active''filter_active');
  80.         $this->setState('filter.active'$active);
  81.  
  82.         $state $this->getUserStateFromRequest($this->context . '.filter.state''filter_state');
  83.         $this->setState('filter.state'$state);
  84.  
  85.         $groupId $this->getUserStateFromRequest($this->context . '.filter.group''filter_group_id'null'int');
  86.         $this->setState('filter.group_id'$groupId);
  87.  
  88.         $range $this->getUserStateFromRequest($this->context . '.filter.range''filter_range');
  89.         $this->setState('filter.range'$range);
  90.  
  91.         $groups json_decode(base64_decode($app->input->get('groups''''BASE64')));
  92.  
  93.         if (isset($groups))
  94.         {
  95.             JArrayHelper::toInteger($groups);
  96.         }
  97.  
  98.         $this->setState('filter.groups'$groups);
  99.  
  100.         $excluded json_decode(base64_decode($app->input->get('excluded''''BASE64')));
  101.  
  102.         if (isset($excluded))
  103.         {
  104.             JArrayHelper::toInteger($excluded);
  105.         }
  106.  
  107.         $this->setState('filter.excluded'$excluded);
  108.  
  109.         // Load the parameters.
  110.         $params JComponentHelper::getParams('com_users');
  111.         $this->setState('params'$params);
  112.  
  113.         // List state information.
  114.         parent::populateState('a.name''asc');
  115.     }
  116.  
  117.     /**
  118.      * Method to get a store id based on model configuration state.
  119.      *
  120.      * This is necessary because the model is used by the component and
  121.      * different modules that might need different sets of data or different
  122.      * ordering requirements.
  123.      *
  124.      * @param   string  $id  A prefix for the store id.
  125.      *
  126.      * @return  string  A store id.
  127.      *
  128.      * @since   1.6
  129.      */
  130.     protected function getStoreId($id '')
  131.     {
  132.         // Compile the store id.
  133.         $id .= ':' $this->getState('filter.search');
  134.         $id .= ':' $this->getState('filter.active');
  135.         $id .= ':' $this->getState('filter.state');
  136.         $id .= ':' $this->getState('filter.group_id');
  137.         $id .= ':' $this->getState('filter.range');
  138.  
  139.         return parent::getStoreId($id);
  140.     }
  141.  
  142.     /**
  143.      * Gets the list of users and adds expensive joins to the result set.
  144.      *
  145.      * @return  mixed  An array of data items on success, false on failure.
  146.      *
  147.      * @since   1.6
  148.      */
  149.     public function getItems()
  150.     {
  151.         // Get a storage key.
  152.         $store $this->getStoreId();
  153.  
  154.         // Try to load the data from internal storage.
  155.         if (empty($this->cache[$store]))
  156.         {
  157.             $groups $this->getState('filter.groups');
  158.             $groupId $this->getState('filter.group_id');
  159.  
  160.             if (isset($groups&& (empty($groups|| $groupId && !in_array($groupId$groups)))
  161.             {
  162.                 $items array();
  163.             }
  164.             else
  165.             {
  166.                 $items parent::getItems();
  167.             }
  168.  
  169.             // Bail out on an error or empty list.
  170.             if (empty($items))
  171.             {
  172.                 $this->cache[$store$items;
  173.  
  174.                 return $items;
  175.             }
  176.  
  177.             // Joining the groups with the main query is a performance hog.
  178.             // Find the information only on the result set.
  179.  
  180.             // First pass: get list of the user id's and reset the counts.
  181.             $userIds array();
  182.  
  183.             foreach ($items as $item)
  184.             {
  185.                 $userIds[= (int) $item->id;
  186.                 $item->group_count 0;
  187.                 $item->group_names '';
  188.                 $item->note_count 0;
  189.             }
  190.  
  191.             // Get the counts from the database only for the users in the list.
  192.             $db $this->getDbo();
  193.             $query $db->getQuery(true);
  194.  
  195.             // Join over the group mapping table.
  196.             $query->select('map.user_id, COUNT(map.group_id) AS group_count')
  197.                 ->from('#__user_usergroup_map AS map')
  198.                 ->where('map.user_id IN (' implode(','$userIds')')
  199.                 ->group('map.user_id')
  200.                 // Join over the user groups table.
  201.                 ->join('LEFT''#__usergroups AS g2 ON g2.id = map.group_id');
  202.  
  203.             $db->setQuery($query);
  204.  
  205.             // Load the counts into an array indexed on the user id field.
  206.             try
  207.             {
  208.                 $userGroups $db->loadObjectList('user_id');
  209.             }
  210.             catch (RuntimeException $e)
  211.             {
  212.                 $this->setError($e->getMessage());
  213.  
  214.                 return false;
  215.             }
  216.  
  217.             $query->clear()
  218.                 ->select('n.user_id, COUNT(n.id) As note_count')
  219.                 ->from('#__user_notes AS n')
  220.                 ->where('n.user_id IN (' implode(','$userIds')')
  221.                 ->where('n.state >= 0')
  222.                 ->group('n.user_id');
  223.  
  224.             $db->setQuery($query);
  225.  
  226.             // Load the counts into an array indexed on the aro.value field (the user id).
  227.             try
  228.             {
  229.                 $userNotes $db->loadObjectList('user_id');
  230.             }
  231.             catch (RuntimeException $e)
  232.             {
  233.                 $this->setError($e->getMessage());
  234.  
  235.                 return false;
  236.             }
  237.  
  238.             // Second pass: collect the group counts into the master items array.
  239.             foreach ($items as &$item)
  240.             {
  241.                 if (isset($userGroups[$item->id]))
  242.                 {
  243.                     $item->group_count $userGroups[$item->id]->group_count;
  244.  
  245.                     // Group_concat in other databases is not supported
  246.                     $item->group_names $this->_getUserDisplayedGroups($item->id);
  247.                 }
  248.  
  249.                 if (isset($userNotes[$item->id]))
  250.                 {
  251.                     $item->note_count $userNotes[$item->id]->note_count;
  252.                 }
  253.             }
  254.  
  255.             // Add the items to the internal cache.
  256.             $this->cache[$store$items;
  257.         }
  258.  
  259.         return $this->cache[$store];
  260.     }
  261.  
  262.     /**
  263.      * Build an SQL query to load the list data.
  264.      *
  265.      * @return  JDatabaseQuery 
  266.      *
  267.      * @since   1.6
  268.      */
  269.     protected function getListQuery()
  270.     {
  271.         // Create a new query object.
  272.         $db $this->getDbo();
  273.         $query $db->getQuery(true);
  274.  
  275.         // Select the required fields from the table.
  276.         $query->select(
  277.             $this->getState(
  278.                 'list.select',
  279.                 'a.*'
  280.             )
  281.         );
  282.  
  283.         $query->from($db->quoteName('#__users'' AS a');
  284.  
  285.         // If the model is set to check item state, add to the query.
  286.         $state $this->getState('filter.state');
  287.  
  288.         if (is_numeric($state))
  289.         {
  290.             $query->where('a.block = ' . (int) $state);
  291.         }
  292.  
  293.         // If the model is set to check the activated state, add to the query.
  294.         $active $this->getState('filter.active');
  295.  
  296.         if (is_numeric($active))
  297.         {
  298.             if ($active == '0')
  299.             {
  300.                 $query->where('a.activation = ' $db->quote(''));
  301.             }
  302.             elseif ($active == '1')
  303.             {
  304.                 $query->where($query->length('a.activation'' = 32');
  305.             }
  306.         }
  307.  
  308.         // Filter the items over the group id if set.
  309.         $groupId $this->getState('filter.group_id');
  310.         $groups $this->getState('filter.groups');
  311.  
  312.         if ($groupId || isset($groups))
  313.         {
  314.             $query->join('LEFT''#__user_usergroup_map AS map2 ON map2.user_id = a.id')
  315.                 ->group($db->quoteName(array('a.id''a.name''a.username''a.password''a.block''a.sendEmail''a.registerDate''a.lastvisitDate''a.activation''a.params''a.email')));
  316.  
  317.             if ($groupId)
  318.             {
  319.                 $query->where('map2.group_id = ' . (int) $groupId);
  320.             }
  321.  
  322.             if (isset($groups))
  323.             {
  324.                 $query->where('map2.group_id IN (' implode(','$groups')');
  325.             }
  326.         }
  327.  
  328.         // Filter the items over the search string if set.
  329.         if ($this->getState('filter.search'!== '' && $this->getState('filter.search'!== null)
  330.         {
  331.             // Escape the search token.
  332.             $token $db->quote('%' $db->escape($this->getState('filter.search')) '%');
  333.  
  334.             // Compile the different search clauses.
  335.             $searches array();
  336.             $searches['a.name LIKE ' $token;
  337.             $searches['a.username LIKE ' $token;
  338.             $searches['a.email LIKE ' $token;
  339.  
  340.             // Add the clauses to the query.
  341.             $query->where('(' implode(' OR '$searches')');
  342.         }
  343.  
  344.         // Add filter for registration ranges select list
  345.         $range $this->getState('filter.range');
  346.  
  347.         // Apply the range filter.
  348.         if ($range)
  349.         {
  350.             // Get UTC for now.
  351.             $dNow new JDate;
  352.             $dStart clone $dNow;
  353.  
  354.             switch ($range)
  355.             {
  356.                 case 'past_week':
  357.                     $dStart->modify('-7 day');
  358.                     break;
  359.  
  360.                 case 'past_1month':
  361.                     $dStart->modify('-1 month');
  362.                     break;
  363.  
  364.                 case 'past_3month':
  365.                     $dStart->modify('-3 month');
  366.                     break;
  367.  
  368.                 case 'past_6month':
  369.                     $dStart->modify('-6 month');
  370.                     break;
  371.  
  372.                 case 'post_year':
  373.                 case 'past_year':
  374.                     $dStart->modify('-1 year');
  375.                     break;
  376.  
  377.                 case 'today':
  378.                     // Ranges that need to align with local 'days' need special treatment.
  379.                     $app JFactory::getApplication();
  380.                     $offset $app->getCfg('offset');
  381.  
  382.                     // Reset the start time to be the beginning of today, local time.
  383.                     $dStart new JDate('now'$offset);
  384.                     $dStart->setTime(000);
  385.  
  386.                     // Now change the timezone back to UTC.
  387.                     $tz new DateTimeZone('GMT');
  388.                     $dStart->setTimezone($tz);
  389.                     break;
  390.             }
  391.  
  392.             if ($range == 'post_year')
  393.             {
  394.                 $query->where(
  395.                     'a.registerDate < ' $db->quote($dStart->format('Y-m-d H:i:s'))
  396.                 );
  397.             }
  398.             else
  399.             {
  400.                 $query->where(
  401.                     'a.registerDate >= ' $db->quote($dStart->format('Y-m-d H:i:s')) .
  402.                         ' AND a.registerDate <=' $db->quote($dNow->format('Y-m-d H:i:s'))
  403.                 );
  404.             }
  405.         }
  406.  
  407.         // Filter by excluded users
  408.         $excluded $this->getState('filter.excluded');
  409.  
  410.         if (!empty($excluded))
  411.         {
  412.             $query->where('id NOT IN (' implode(','$excluded')');
  413.         }
  414.  
  415.         // Add the list ordering clause.
  416.         $query->order($db->escape($this->getState('list.ordering''a.name')) ' ' $db->escape($this->getState('list.direction''ASC')));
  417.  
  418.         return $query;
  419.     }
  420.  
  421.     /**
  422.      * SQL server change
  423.      *
  424.      * @param   integer  $user_id  User identifier
  425.      *
  426.      * @return  string             Groups titles imploded :$
  427.      */
  428.     function _getUserDisplayedGroups($user_id)
  429.     {
  430.         $db JFactory::getDbo();
  431.         $query "SELECT title FROM " $db->quoteName('#__usergroups'" ug left join " .
  432.             $db->quoteName('#__user_usergroup_map'" map on (ug.id = map.group_id)" .
  433.             " WHERE map.user_id=" . (int) $user_id;
  434.  
  435.         $db->setQuery($query);
  436.         $result $db->loadColumn();
  437.  
  438.         return implode("\n"$result);
  439.     }
  440. }

Documentation generated on Tue, 19 Nov 2013 15:16:39 +0100 by phpDocumentor 1.4.3