/** * Displays a list of user groups. * * @param boolean $includeSuperAdmin true to include super admin groups, false to exclude them * * @return array An array containing a list of user groups. * * @since 11.4 */ public static function groups($includeSuperAdmin = false) { $db = Factory::getDbo(); $query = $db->getQuery(true); $query->select('a.id AS value, a.title AS text, COUNT(DISTINCT b.id) AS level'); $query->from($db->quoteName('#__usergroups') . ' AS a'); $query->join('LEFT', $db->quoteName('#__usergroups') . ' AS b ON a.lft > b.lft AND a.rgt < b.rgt'); $query->group('a.id, a.title, a.lft, a.rgt'); $query->order('a.lft ASC'); $db->setQuery($query); $options = $db->loadObjectList(); for ($i = 0, $n = count($options); $i < $n; $i++) { $options[$i]->text = str_repeat('- ', $options[$i]->level) . $options[$i]->text; $groups[] = Html::_('select.option', $options[$i]->value, $options[$i]->text); } // Exclude super admin groups if requested if (!$includeSuperAdmin) { $filteredGroups = array(); foreach ($groups as $group) { if (!AccessAccess::checkGroup($group->value, 'core.admin')) { $filteredGroups[] = $group; } } $groups = $filteredGroups; } return $groups; }
/** * Method to get a list of options for a list input. * * @return array An array of JHtml options. * * @since 11.4 */ protected function getOptions() { $folder = $this->element['folder']; if (!empty($folder)) { // Get list of plugins $db = Factory::getDbo(); $query = $db->getQuery(true); $query->select('element AS value, name AS text'); $query->from('#__extensions'); $query->where('folder = ' . $db->q($folder)); $query->where('enabled = 1'); $query->order('ordering, name'); $db->setQuery($query); $options = $db->loadObjectList(); $lang = Factory::getLanguage(); foreach ($options as $i => $item) { $source = JPATH_PLUGINS . '/' . $folder . '/' . $item->value; $extension = 'plg_' . $folder . '_' . $item->value; $lang->load($extension . '.sys', JPATH_ADMINISTRATOR, null, false, false) || $lang->load($extension . '.sys', $source, null, false, false) || $lang->load($extension . '.sys', JPATH_ADMINISTRATOR, $lang->getDefault(), false, false) || $lang->load($extension . '.sys', $source, $lang->getDefault(), false, false); $options[$i]->text = Text::_($item->text); } } else { Log::add(Text::_('JFRAMEWORK_FORM_FIELDS_PLUGINS_ERROR_FOLDER_EMPTY'), Log::WARNING, 'jerror'); } // Merge any additional options in the XML definition. $options = array_merge(parent::getOptions(), $options); return $options; }
/** * Method to get the field input markup for Access Control Lists. * Optionally can be associated with a specific component and section. * * TODO: Add access check. * * @return string The field input markup. * * @since 11.1 */ protected function getInput() { Html::_('behavior.tooltip'); // Initialise some field attributes. $section = $this->element['section'] ? (string) $this->element['section'] : ''; $component = $this->element['component'] ? (string) $this->element['component'] : ''; $assetField = $this->element['asset_field'] ? (string) $this->element['asset_field'] : 'asset_id'; // Get the actions for the asset. $actions = Access::getActionsFromFile(JPATH_ADMINISTRATOR . '/components/' . $component . '/access.xml', "/access/section[@name='" . $section . "']/"); // Iterate over the children and add to the actions. foreach ($this->element->children() as $el) { if ($el->getName() == 'action') { $actions[] = (object) array('name' => (string) $el['name'], 'title' => (string) $el['title'], 'description' => (string) $el['description']); } } // Get the explicit rules for this asset. if ($section == 'component') { // Need to find the asset id by the name of the component. $db = Factory::getDbo(); $query = $db->getQuery(true); $query->select($db->quoteName('id')); $query->from($db->quoteName('#__assets')); $query->where($db->quoteName('name') . ' = ' . $db->quote($component)); $db->setQuery($query); $assetId = (int) $db->loadResult(); } else { // Find the asset id of the content. // Note that for global configuration, com_config injects asset_id = 1 into the form. $assetId = $this->form->getValue($assetField); } // Use the compact form for the content rules (deprecated). /* @todo remove code: if (!empty($component) && $section != 'component') { return Html::_('rules.assetFormWidget', $actions, $assetId, $assetId ? null : $component, $this->name, $this->id); } */ // Full width format. // Get the rules for just this asset (non-recursive). $assetRules = Access::getAssetRules($assetId); // Get the available user groups. $groups = $this->getUserGroups(); // Build the form control. $curLevel = 0; // Prepare output $html = array(); $html[] = '<div id="permissions-sliders" class="pane-sliders">'; $html[] = '<p class="rule-desc">' . Text::_('JLIB_RULES_SETTINGS_DESC') . '</p>'; $html[] = '<ul id="rules">'; // Start a row for each user group. foreach ($groups as $group) { $difLevel = $group->level - $curLevel; if ($difLevel > 0) { $html[] = '<li><ul>'; } elseif ($difLevel < 0) { $html[] = str_repeat('</ul></li>', -$difLevel); } $html[] = '<li>'; $html[] = '<div class="panel">'; $html[] = '<h3 class="pane-toggler title"><a href="javascript:void(0);"><span>'; $html[] = str_repeat('<span class="level">|–</span> ', $curLevel = $group->level) . $group->text; $html[] = '</span></a></h3>'; $html[] = '<div class="pane-slider content pane-hide">'; $html[] = '<div class="mypanel">'; $html[] = '<table class="group-rules">'; $html[] = '<thead>'; $html[] = '<tr>'; $html[] = '<th class="actions" id="actions-th' . $group->value . '">'; $html[] = '<span class="acl-action">' . Text::_('JLIB_RULES_ACTION') . '</span>'; $html[] = '</th>'; $html[] = '<th class="settings" id="settings-th' . $group->value . '">'; $html[] = '<span class="acl-action">' . Text::_('JLIB_RULES_SELECT_SETTING') . '</span>'; $html[] = '</th>'; // The calculated setting is not shown for the root group of global configuration. $canCalculateSettings = $group->parent_id || !empty($component); if ($canCalculateSettings) { $html[] = '<th id="aclactionth' . $group->value . '">'; $html[] = '<span class="acl-action">' . Text::_('JLIB_RULES_CALCULATED_SETTING') . '</span>'; $html[] = '</th>'; } $html[] = '</tr>'; $html[] = '</thead>'; $html[] = '<tbody>'; foreach ($actions as $action) { $html[] = '<tr>'; $html[] = '<td headers="actions-th' . $group->value . '">'; $html[] = '<label class="hasTip" for="' . $this->id . '_' . $action->name . '_' . $group->value . '" title="' . htmlspecialchars(Text::_($action->title) . '::' . Text::_($action->description), ENT_COMPAT, 'UTF-8') . '">'; $html[] = Text::_($action->title); $html[] = '</label>'; $html[] = '</td>'; $html[] = '<td headers="settings-th' . $group->value . '">'; $html[] = '<select name="' . $this->name . '[' . $action->name . '][' . $group->value . ']" id="' . $this->id . '_' . $action->name . '_' . $group->value . '" title="' . Text::sprintf('JLIB_RULES_SELECT_ALLOW_DENY_GROUP', Text::_($action->title), trim($group->text)) . '">'; $inheritedRule = Access::checkGroup($group->value, $action->name, $assetId); // Get the actual setting for the action for this group. $assetRule = $assetRules->allow($action->name, $group->value); // Build the dropdowns for the permissions sliders // The parent group has "Not Set", all children can rightly "Inherit" from that. $html[] = '<option value=""' . ($assetRule === null ? ' selected="selected"' : '') . '>' . Text::_(empty($group->parent_id) && empty($component) ? 'JLIB_RULES_NOT_SET' : 'JLIB_RULES_INHERITED') . '</option>'; $html[] = '<option value="1"' . ($assetRule === true ? ' selected="selected"' : '') . '>' . Text::_('JLIB_RULES_ALLOWED') . '</option>'; $html[] = '<option value="0"' . ($assetRule === false ? ' selected="selected"' : '') . '>' . Text::_('JLIB_RULES_DENIED') . '</option>'; $html[] = '</select>  '; // If this asset's rule is allowed, but the inherited rule is deny, we have a conflict. if ($assetRule === true && $inheritedRule === false) { $html[] = Text::_('JLIB_RULES_CONFLICT'); } $html[] = '</td>'; // Build the Calculated Settings column. // The inherited settings column is not displayed for the root group in global configuration. if ($canCalculateSettings) { $html[] = '<td headers="aclactionth' . $group->value . '">'; // This is where we show the current effective settings considering currrent group, path and cascade. // Check whether this is a component or global. Change the text slightly. if (Access::checkGroup($group->value, 'core.admin') !== true) { if ($inheritedRule === null) { $html[] = '<span class="icon-16-unset">' . Text::_('JLIB_RULES_NOT_ALLOWED') . '</span>'; } elseif ($inheritedRule === true) { $html[] = '<span class="icon-16-allowed">' . Text::_('JLIB_RULES_ALLOWED') . '</span>'; } elseif ($inheritedRule === false) { if ($assetRule === false) { $html[] = '<span class="icon-16-denied">' . Text::_('JLIB_RULES_NOT_ALLOWED') . '</span>'; } else { $html[] = '<span class="icon-16-denied"><span class="icon-16-locked">' . Text::_('JLIB_RULES_NOT_ALLOWED_LOCKED') . '</span></span>'; } } } elseif (!empty($component)) { $html[] = '<span class="icon-16-allowed"><span class="icon-16-locked">' . Text::_('JLIB_RULES_ALLOWED_ADMIN') . '</span></span>'; } else { // Special handling for groups that have global admin because they can't be denied. // The admin rights can be changed. if ($action->name === 'core.admin') { $html[] = '<span class="icon-16-allowed">' . Text::_('JLIB_RULES_ALLOWED') . '</span>'; } elseif ($inheritedRule === false) { // Other actions cannot be changed. $html[] = '<span class="icon-16-denied"><span class="icon-16-locked">' . Text::_('JLIB_RULES_NOT_ALLOWED_ADMIN_CONFLICT') . '</span></span>'; } else { $html[] = '<span class="icon-16-allowed"><span class="icon-16-locked">' . Text::_('JLIB_RULES_ALLOWED_ADMIN') . '</span></span>'; } } $html[] = '</td>'; } $html[] = '</tr>'; } $html[] = '</tbody>'; $html[] = '</table></div>'; $html[] = '</div></div>'; $html[] = '</li>'; } $html[] = str_repeat('</ul></li>', $curLevel); $html[] = '</ul><div class="rule-notes">'; if ($section == 'component' || $section == null) { $html[] = Text::_('JLIB_RULES_SETTING_NOTES'); } else { $html[] = Text::_('JLIB_RULES_SETTING_NOTES_ITEM'); } $html[] = '</div></div>'; // Get the JInput object $input = Factory::getApplication()->input; $js = "window.addEvent('domready', function(){ new Fx.Accordion(\$\$('div#permissions-sliders.pane-sliders .panel h3.pane-toggler')," . "\$\$('div#permissions-sliders.pane-sliders .panel div.pane-slider'), {onActive: function(toggler, i) {toggler.addClass('pane-toggler-down');" . "toggler.removeClass('pane-toggler');i.addClass('pane-down');i.removeClass('pane-hide');Cookie.write('jpanesliders_permissions-sliders" . $component . "',\$\$('div#permissions-sliders.pane-sliders .panel h3').indexOf(toggler));}," . "onBackground: function(toggler, i) {toggler.addClass('pane-toggler');toggler.removeClass('pane-toggler-down');i.addClass('pane-hide');" . "i.removeClass('pane-down');}, duration: 300, display: " . $input->cookie->get('jpanesliders_permissions-sliders' . $component, 0, 'integer') . ", show: " . $input->cookie->get('jpanesliders_permissions-sliders' . $component, 0, 'integer') . ", alwaysHide:true, opacity: false}); });"; Factory::getDocument()->addScriptDeclaration($js); return implode("\n", $html); }
/** * Garbage collect stale sessions from the SessionHandler backend. * * @param integer $lifetime The maximum age of a session. * * @return boolean True on success, false otherwise. * * @since 11.1 */ public function gc($lifetime = 1440) { // Get the database connection object and verify that it is connected. $db = Factory::getDbo(); // Determine the timestamp threshold with which to purge old sessions. $past = time() - $lifetime; try { $query = $db->getQuery(true); $query->delete($db->quoteName('#__session'))->where($db->quoteName('time') . ' < ' . $db->quote((int) $past)); // Remove expired sessions from the database. $db->setQuery($query); return (bool) $db->execute(); } catch (Exception $e) { return false; } }
/** * Gets a list of the asset groups as an array of JHtml compatible options. * * @return mixed An array or false if an error occurs * * @since 11.1 */ public static function assetgroups() { if (empty(self::$asset_groups)) { $db = Factory::getDbo(); $query = $db->getQuery(true); $query->select('a.id AS value, a.title AS text'); $query->from($db->quoteName('#__viewlevels') . ' AS a'); $query->group('a.id, a.title, a.ordering'); $query->order('a.ordering ASC'); $db->setQuery($query); self::$asset_groups = $db->loadObjectList(); } return self::$asset_groups; }
/** * Select list of active users * * @param string $name The name of the field * @param string $active The active user * @param integer $nouser If set include an option to select no user * @param string $javascript Custom javascript * @param string $order Specify a field to order by * * @return string The HTML for a list of users list of users * * @since 11.1 */ public static function users($name, $active, $nouser = 0, $javascript = null, $order = 'name') { $db = Factory::getDbo(); $query = $db->getQuery(true); $query->select('u.id AS value, u.name AS text'); $query->from('#__users AS u'); $query->join('LEFT', '#__user_usergroup_map AS m ON m.user_id = u.id'); $query->where('u.block = 0'); $query->order($order); $query->group('u.id'); $db->setQuery($query); if ($nouser) { $users[] = Html::_('select.option', '0', Text::_('JOPTION_NO_USER')); $users = array_merge($users, $db->loadObjectList()); } else { $users = $db->loadObjectList(); } $users = Html::_('select.genericlist', $users, $name, array('list.attr' => 'class="inputbox" size="1" ' . $javascript, 'list.select' => $active)); return $users; }
/** * Method to return a list of all categories that a user has permission for a given action * * @param string $component The component from which to retrieve the categories * @param string $action The name of the section within the component from which to retrieve the actions. * * @return array List of categories that this group can do this action to (empty array if none). Categories must be published. * * @since 11.1 */ public function getAuthorisedCategories($component, $action) { // Brute force method: get all published category rows for the component and check each one // TODO: Modify the way permissions are stored in the db to allow for faster implementation and better scaling $db = Factory::getDbo(); $query = $db->getQuery(true)->select('c.id AS id, a.name AS asset_name')->from('#__categories AS c')->innerJoin('#__assets AS a ON c.asset_id = a.id')->where('c.extension = ' . $db->quote($component))->where('c.published = 1'); $db->setQuery($query); $allCategories = $db->loadObjectList('id'); $allowedCategories = array(); foreach ($allCategories as $category) { if ($this->authorise($action, $category->asset_name)) { $allowedCategories[] = (int) $category->id; } } return $allowedCategories; }
/** * Method to return a list of user Ids contained in a Group * * @param integer $groupId The group Id * @param boolean $recursive Recursively include all child groups (optional) * * @return array * * @since 11.1 * @todo This method should move somewhere else */ public static function getUsersByGroup($groupId, $recursive = false) { // Get a database object. $db = Factory::getDbo(); $test = $recursive ? '>=' : '='; // First find the users contained in the group $query = $db->getQuery(true); $query->select('DISTINCT(user_id)'); $query->from('#__usergroups as ug1'); $query->join('INNER', '#__usergroups AS ug2 ON ug2.lft' . $test . 'ug1.lft AND ug1.rgt' . $test . 'ug2.rgt'); $query->join('INNER', '#__user_usergroup_map AS m ON ug2.id=m.group_id'); $query->where('ug1.id=' . $db->Quote($groupId)); $db->setQuery($query); $result = $db->loadColumn(); // Clean up any NULL values, just in case ArrayHelper::toInteger($result); return $result; }
/** * Count the number of child menu items * * @return integer Number of child menu items * * @since 11.1 */ public function countMenuChildren() { static $children; if (!isset($children)) { $dbo = Factory::getDbo(); $app = Factory::getApplication(); $menu = $app->getMenu(); $active = $menu->getActive(); if ($active) { $query = $dbo->getQuery(true); $query->select('COUNT(*)'); $query->from('#__menu'); $query->where('parent_id = ' . $active->id); $query->where('published = 1'); $children = $dbo->loadResult(); } else { $children = 0; } } return $children; }
/** * Returns userid if a user exists * * @param string $username The username to search on. * * @return integer The user id or 0 if not found. * * @since 11.1 */ public static function getUserId($username) { // Initialise some variables $db = Factory::getDbo(); $query = $db->getQuery(true); $query->select($db->quoteName('id')); $query->from($db->quoteName('#__users')); $query->where($db->quoteName('username') . ' = ' . $db->quote($username)); $db->setQuery($query, 0, 1); return $db->loadResult(); }
/** * Load the database driver. * * @return Driver The database driver. * * @since 12.1 */ protected function loadDb() { return Factory::getDbo(); }
/** * Static method to get an instance of a JTable class if it can be found in * the table include paths. To add include paths for searching for JTable * classes @see JTable::addIncludePath(). * * @param string $type The type (name) of the JTable class to get an instance of. * @param string $prefix An optional prefix for the table class name. * @param array $config An optional array of configuration values for the JTable object. * * @return mixed A JTable object if found or boolean false if one could not be found. * * @link http://docs.joomla.org/JTable/getInstance * @since 11.1 */ public static function getInstance($type, $prefix = 'JTable', $config = array()) { // Sanitize and prepare the table class name. $type = preg_replace('/[^A-Z0-9_\\.-]/i', '', $type); $tableClass = $prefix . ucfirst($type); // Only try to load the class if it doesn't already exist. if (!class_exists($tableClass)) { // Search for the class file in the JTable include paths. $path = Path::find(self::addIncludePath(), strtolower($type) . '.php'); if ($path) { // Import the class file. include_once $path; // If we were unable to load the proper class, raise a warning and return false. if (!class_exists($tableClass)) { Log::add(Text::sprintf('JLIB_DATABASE_ERROR_CLASS_NOT_FOUND_IN_FILE', $tableClass), Log::WARNING, 'jerror'); return false; } } else { // If we were unable to find the class file in the JTable include paths, raise a warning and return false. Log::add(Text::sprintf('JLIB_DATABASE_ERROR_NOT_SUPPORTED_FILE_NOT_FOUND', $type), Log::WARNING, 'jerror'); return false; } } // If a database object was passed in the configuration array use it, otherwise get the global one from JFactory. $db = isset($config['dbo']) ? $config['dbo'] : Factory::getDbo(); // Instantiate a new table class and return it. return new $tableClass($db); }
/** * Gets the date as an SQL datetime string. * * @param boolean $local True to return the date string in the local time zone, false to return it in GMT. * @param JDatabaseDriver $dbo The database driver or null to use JFactory::getDbo() * * @return string The date string in SQL datetime format. * * @link http://dev.mysql.com/doc/refman/5.0/en/datetime.html * @since 11.4 */ public function toSql($local = false, Driver $dbo = null) { if ($dbo === null) { $dbo = Factory::getDbo(); } return $this->format($dbo->getDateFormat(), $local, false); }
/** * Loads the published plugins. * * @return array An array of published plugins * * @since 11.1 */ protected static function _load() { if (self::$plugins !== null) { return self::$plugins; } $user = Factory::getUser(); $cache = Factory::getCache('com_plugins', ''); $levels = implode(',', $user->getAuthorisedViewLevels()); if (!(self::$plugins = $cache->get($levels))) { $db = Factory::getDbo(); $query = $db->getQuery(true); $query->select('folder AS type, element AS name, params')->from('#__extensions')->where('enabled >= 1')->where('type =' . $db->Quote('plugin'))->where('state >= 0')->where('access IN (' . $levels . ')')->order('ordering'); self::$plugins = $db->setQuery($query)->loadObjectList(); $cache->store(self::$plugins, $levels); } return self::$plugins; }