1: <?php
2: /**
3: * user select with page navigation
4: *
5: * limit: Only work with javascript enabled
6: *
7: * You may not change or alter any portion of this comment or credits
8: * of supporting developers from this source code or any supporting source code
9: * which is considered copyrighted (c) material of the original comment or credit authors.
10: * This program is distributed in the hope that it will be useful,
11: * but WITHOUT ANY WARRANTY; without even the implied warranty of
12: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13: *
14: * @copyright The XOOPS Project (https://xoops.org)
15: * @license GNU GPL 2 (https://www.gnu.org/licenses/gpl-2.0.html)
16: * @package kernel
17: * @subpackage form
18: * @since 2.0.0
19: * @author Taiwen Jiang <phppp@users.sourceforge.net>
20: */
21: defined('XOOPS_ROOT_PATH') || exit('Restricted access');
22:
23: xoops_load('XoopsFormElementTray');
24: xoops_load('XoopsFormSelect');
25:
26: /**
27: * User Select field
28: */
29: class XoopsFormSelectUser extends XoopsFormElementTray
30: {
31: /**
32: * Constructor
33: *
34: * @param string $caption form element caption
35: * @param string $name form element name
36: * @param bool $includeAnonymous Include user "anonymous"?
37: * @param mixed $value Pre-selected value (or array of them).
38: * For an item with massive members, such as "Registered Users", "$value"
39: * should be used to store selected temporary users only instead of all
40: * members of that item
41: * @param int $size Number of rows. "1" makes a drop-down-list.
42: * @param bool $multiple Allow multiple selections?
43: */
44: public function __construct($caption, $name, $includeAnonymous = false, $value = null, $size = 1, $multiple = false)
45: {
46: /**
47: * @var mixed array|false - cache any result for this session.
48: * Some modules use multiple copies of this element on a single page, so this call will
49: * be made multiple times. This is only used when $value is null.
50: * @todo this should be replaced with better interface, with autocomplete style search
51: * and user specific MRU cache
52: */
53: static $queryCache = false;
54:
55: /**
56: * @var int - limit to this many rows
57: */
58: $limit = 200;
59:
60: /**
61: * @var string - cache time to live - will be interpreted by strtotime()
62: */
63: $cachettl = '+5 minutes';
64:
65: /**
66: * @var string - cache key
67: */
68: $cachekey = 'formselectuser';
69:
70: $select_element = new XoopsFormSelect('', $name, $value, $size, $multiple);
71: if ($includeAnonymous) {
72: $select_element->addOption(0, $GLOBALS['xoopsConfig']['anonymous']);
73: }
74: /** @var XoopsMemberHandler $member_handler */
75: $member_handler = xoops_getHandler('member');
76: $value = is_array($value) ? $value : (empty($value) ? array() : array($value));
77: $selectedUsers = array();
78: if (count($value) > 0) {
79: // fetch the set of uids in $value
80: $criteria = new Criteria('uid', '(' . implode(',', $value) . ')', 'IN');
81: $criteria->setSort('uname');
82: $criteria->setOrder('ASC');
83: $selectedUsers = $member_handler->getUserList($criteria);
84: }
85:
86: // get the full selection list
87: // we will always cache this version to reduce expense
88: if (empty($queryCache)) {
89: XoopsLoad::load('XoopsCache');
90: $queryCache = XoopsCache::read($cachekey);
91: if ($queryCache === false) {
92: $criteria = new CriteriaCompo();
93: if ($limit <= $member_handler->getUserCount()) {
94: // if we have more than $limit users, we will select who to show based on last_login
95: $criteria->setLimit($limit);
96: $criteria->setSort('last_login');
97: $criteria->setOrder('DESC');
98: } else {
99: $criteria->setSort('uname');
100: $criteria->setOrder('ASC');
101: }
102: $queryCache = $member_handler->getUserList($criteria);
103: asort($queryCache);
104: XoopsCache::write($cachekey, $queryCache, $cachettl); // won't do anything different if write fails
105: }
106: }
107:
108: // merge with selected
109: $users = $selectedUsers + $queryCache;
110:
111: $select_element->addOptionArray($users);
112: if ($limit > count($users)) {
113: parent::__construct($caption, '', $name);
114: $this->addElement($select_element);
115:
116: return null;
117: }
118:
119: xoops_loadLanguage('findusers');
120: $js_addusers = "
121: function addusers(opts)
122: {
123: var num = opts.substring(0, opts.indexOf(':'));
124: opts = opts.substring(opts.indexOf(':')+1, opts.length);
125: var sel = xoopsGetElementById('" . $name . "');
126: var arr = new Array(num);
127: for (var n=0; n < num; n++) {
128: var nm = opts.substring(0, opts.indexOf(':'));
129: opts = opts.substring(opts.indexOf(':')+1, opts.length);
130: var val = opts.substring(0, opts.indexOf(':'));
131: opts = opts.substring(opts.indexOf(':')+1, opts.length);
132: var txt = opts.substring(0, nm - val.length);
133: opts = opts.substring(nm - val.length, opts.length);
134: var added = false;
135: for (var k = 0; k < sel.options.length; k++) {
136: if (sel.options[k].value == val) {
137: added = true;
138: sel.options[k].selected = true;
139: break;
140: }
141: }
142: if (added == false) {
143: sel.options[k] = new Option(txt, val);
144: sel.options[k].selected = true;
145: }
146: }
147:
148: return true;
149: }";
150: $token = $GLOBALS['xoopsSecurity']->createToken();
151: $action_tray = new XoopsFormElementTray('', '');
152: $removeUsers = new XoopsFormButton('', 'rmvusr_' . $name, _MA_USER_REMOVE, 'button');
153: $removeUsers->setExtra(' onclick="var sel = xoopsGetElementById(\'' . $name . '\');for (var i = sel.options.length-1; i >= 0; i--) {if (!sel.options[i].selected) {sel.options[i] = null;}}; return false;" ');
154: $action_tray->addElement($removeUsers);
155:
156: $searchUsers = new XoopsFormButton('', 'srchusr_' . $name, _MA_USER_MORE, 'button');
157: $searchUsers->setExtra(' onclick="openWithSelfMain(\'' . XOOPS_URL . '/include/findusers.php?target=' . $name . '&amp;multiple=' . $multiple . '&amp;token=' . $token . '\', \'userselect\', 800, 600, null); return false;" ');
158: $action_tray->addElement($searchUsers);
159:
160: if (isset($GLOBALS['xoTheme']) && is_object($GLOBALS['xoTheme'])) {
161: $GLOBALS['xoTheme']->addScript('', array(), $js_addusers);
162: } else {
163: echo '<script>' . $js_addusers . '</script>';
164: }
165: parent::__construct($caption, '', $name);
166: $this->addElement($select_element);
167: $this->addElement($action_tray);
168: }
169: }
170: