File manager - Edit - /home/verseaumee/empowernetkenyajuly2026/Helper.tar
Back
WrapperHelper.php 0000604 00000002740 15251774774 0010057 0 ustar 00 <?php /** * @package Joomla.Site * @subpackage mod_wrapper * * @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Module\Wrapper\Site\Helper; \defined('_JEXEC') or die; use Joomla\CMS\Factory; /** * Helper for mod_wrapper * * @since 1.5 */ class WrapperHelper { /** * Gets the parameters for the wrapper * * @param mixed &$params The parameters set in the administrator section * * @return mixed &$params The modified parameters * * @since 1.5 */ public static function getParams(&$params) { $params->def('url', ''); $params->def('scrolling', 'auto'); $params->def('height', '200'); $params->def('height_auto', 0); $params->def('width', '100%'); $params->def('add', 1); $params->def('name', 'wrapper'); $url = $params->get('url'); if ($params->get('add')) { // Adds 'http://' if none is set if (strpos($url, '/') === 0) { // Relative URL in component. use server http_host. $url = 'http://' . Factory::getApplication()->input->server->get('HTTP_HOST') . $url; } elseif (strpos($url, 'http') === false && strpos($url, 'https') === false) { $url = 'http://' . $url; } } $load = ''; // Auto height control if ($params->def('height_auto')) { $load = 'onload="iFrameHeight(this)"'; } $params->set('load', $load); $params->set('url', $url); return $params; } } ModuleHelper.php 0000604 00000045671 15252027330 0007652 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2005 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Helper; \defined('JPATH_PLATFORM') or die; use Joomla\CMS\Cache\CacheControllerFactoryInterface; use Joomla\CMS\Cache\Controller\CallbackController; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Factory; use Joomla\CMS\Filesystem\Path; use Joomla\CMS\Filter\InputFilter; use Joomla\CMS\Language\LanguageHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\Layout\LayoutHelper; use Joomla\CMS\Log\Log; use Joomla\CMS\Profiler\Profiler; use Joomla\Database\ParameterType; use Joomla\Registry\Registry; /** * Module helper class * * @since 1.5 */ abstract class ModuleHelper { /** * Get module by name (real, eg 'Breadcrumbs' or folder, eg 'mod_breadcrumbs') * * @param string $name The name of the module * @param string $title The title of the module, optional * * @return \stdClass The Module object * * @since 1.5 */ public static function &getModule($name, $title = null) { $result = null; $modules =& static::load(); $total = \count($modules); for ($i = 0; $i < $total; $i++) { // Match the name of the module if ($modules[$i]->name === $name || $modules[$i]->module === $name) { // Match the title if we're looking for a specific instance of the module if (!$title || $modules[$i]->title === $title) { // Found it $result = &$modules[$i]; break; } } } // If we didn't find it, and the name is mod_something, create a dummy object if ($result === null && strpos($name, 'mod_') === 0) { $result = static::createDummyModule(); $result->module = $name; } return $result; } /** * Get modules by position * * @param string $position The position of the module * * @return array An array of module objects * * @since 1.5 */ public static function &getModules($position) { $position = strtolower($position); $result = array(); $input = Factory::getApplication()->input; $modules =& static::load(); $total = \count($modules); for ($i = 0; $i < $total; $i++) { if ($modules[$i]->position === $position) { $result[] = &$modules[$i]; } } if (\count($result) === 0) { if ($input->getBool('tp') && ComponentHelper::getParams('com_templates')->get('template_positions_display')) { $result[0] = static::createDummyModule(); $result[0]->title = $position; $result[0]->position = $position; } } return $result; } /** * Checks if a module is enabled. A given module will only be returned * if it meets the following criteria: it is enabled, it is assigned to * the current menu item or all items, and the user meets the access level * requirements. * * @param string $module The module name * * @return boolean See description for conditions. * * @since 1.5 */ public static function isEnabled($module) { $result = static::getModule($module); return $result !== null && $result->id !== 0; } /** * Render the module. * * @param object $module A module object. * @param array $attribs An array of attributes for the module (probably from the XML). * * @return string The HTML content of the module output. * * @since 1.5 */ public static function renderModule($module, $attribs = array()) { $app = Factory::getApplication(); // Check that $module is a valid module object if (!\is_object($module) || !isset($module->module) || !isset($module->params)) { if (JDEBUG) { Log::addLogger(array('text_file' => 'jmodulehelper.log.php'), Log::ALL, array('modulehelper')); $app->getLogger()->debug( __METHOD__ . '() - The $module parameter should be a module object.', array('category' => 'modulehelper') ); } return ''; } // Get module parameters $params = new Registry($module->params); // Render the module content static::renderRawModule($module, $params, $attribs); // Return early if only the content is required if (!empty($attribs['contentOnly'])) { return $module->content; } if (JDEBUG) { Profiler::getInstance('Application')->mark('beforeRenderModule ' . $module->module . ' (' . $module->title . ')'); } // Record the scope. $scope = $app->scope; // Set scope to component name $app->scope = $module->module; // Get the template $template = $app->getTemplate(); // Check if the current module has a style param to override template module style $paramsChromeStyle = $params->get('style'); $basePath = ''; if ($paramsChromeStyle) { $paramsChromeStyle = explode('-', $paramsChromeStyle, 2); $ChromeStyleTemplate = strtolower($paramsChromeStyle[0]); $attribs['style'] = $paramsChromeStyle[1]; // Only set $basePath if the specified template isn't the current or system one. if ($ChromeStyleTemplate !== $template && $ChromeStyleTemplate !== 'system') { $basePath = JPATH_THEMES . '/' . $ChromeStyleTemplate . '/html/layouts'; } } // Make sure a style is set if (!isset($attribs['style'])) { $attribs['style'] = 'none'; } // Dynamically add outline style if ($app->input->getBool('tp') && ComponentHelper::getParams('com_templates')->get('template_positions_display')) { $attribs['style'] .= ' outline'; } $module->style = $attribs['style']; // If the $module is nulled it will return an empty content, otherwise it will render the module normally. $app->triggerEvent('onRenderModule', array(&$module, &$attribs)); if ($module === null || !isset($module->content)) { return ''; } $displayData = array( 'module' => $module, 'params' => $params, 'attribs' => $attribs, ); foreach (explode(' ', $attribs['style']) as $style) { if ($moduleContent = LayoutHelper::render('chromes.' . $style, $displayData, $basePath)) { $module->content = $moduleContent; } } // Revert the scope $app->scope = $scope; $app->triggerEvent('onAfterRenderModule', array(&$module, &$attribs)); if (JDEBUG) { Profiler::getInstance('Application')->mark('afterRenderModule ' . $module->module . ' (' . $module->title . ')'); } return $module->content; } /** * Render the module content. * * @param object $module A module object * @param Registry $params A module parameters * @param array $attribs An array of attributes for the module (probably from the XML). * * @return string * * @since 4.0.0 */ public static function renderRawModule($module, Registry $params, $attribs = array()) { if (!empty($module->contentRendered)) { return $module->content; } if (JDEBUG) { Profiler::getInstance('Application')->mark('beforeRenderRawModule ' . $module->module . ' (' . $module->title . ')'); } $app = Factory::getApplication(); // Record the scope. $scope = $app->scope; // Set scope to component name $app->scope = $module->module; // Get module path $module->module = preg_replace('/[^A-Z0-9_\.-]/i', '', $module->module); $dispatcher = $app->bootModule($module->module, $app->getName())->getDispatcher($module, $app); // Check if we have a dispatcher if ($dispatcher) { ob_start(); $dispatcher->dispatch(); $module->content = ob_get_clean(); } // Add the flag that the module content has been rendered $module->contentRendered = true; // Revert the scope $app->scope = $scope; if (JDEBUG) { Profiler::getInstance('Application')->mark('afterRenderRawModule ' . $module->module . ' (' . $module->title . ')'); } return $module->content; } /** * Get the path to a layout for a module * * @param string $module The name of the module * @param string $layout The name of the module layout. If alternative layout, in the form template:filename. * * @return string The path to the module layout * * @since 1.5 */ public static function getLayoutPath($module, $layout = 'default') { $templateObj = Factory::getApplication()->getTemplate(true); $defaultLayout = $layout; $template = $templateObj->template; if (strpos($layout, ':') !== false) { // Get the template and file name from the string $temp = explode(':', $layout); $template = $temp[0] === '_' ? $template : $temp[0]; $layout = $temp[1]; $defaultLayout = $temp[1] ?: 'default'; } $dPath = JPATH_BASE . '/modules/' . $module . '/tmpl/default.php'; try { // Build the template and base path for the layout $tPath = Path::check(JPATH_THEMES . '/' . $template . '/html/' . $module . '/' . $layout . '.php'); $iPath = Path::check(JPATH_THEMES . '/' . $templateObj->parent . '/html/' . $module . '/' . $layout . '.php'); $bPath = Path::check(JPATH_BASE . '/modules/' . $module . '/tmpl/' . $defaultLayout . '.php'); } catch (\Exception $e) { // On error fallback to the default path return $dPath; } // If the template has a layout override use it if (is_file($tPath)) { return $tPath; } if (!empty($templateObj->parent) && is_file($iPath)) { return $iPath; } if (is_file($bPath)) { return $bPath; } return $dPath; } /** * Load published modules. * * @return array * * @since 3.2 */ protected static function &load() { static $modules; if (isset($modules)) { return $modules; } $app = Factory::getApplication(); $modules = null; $app->triggerEvent('onPrepareModuleList', array(&$modules)); // If the onPrepareModuleList event returns an array of modules, then ignore the default module list creation if (!\is_array($modules)) { $modules = static::getModuleList(); } $app->triggerEvent('onAfterModuleList', array(&$modules)); $modules = static::cleanModuleList($modules); $app->triggerEvent('onAfterCleanModuleList', array(&$modules)); return $modules; } /** * Module list * * @return array */ public static function getModuleList() { $app = Factory::getApplication(); $itemId = $app->input->getInt('Itemid', 0); $groups = $app->getIdentity()->getAuthorisedViewLevels(); $clientId = (int) $app->getClientId(); // Build a cache ID for the resulting data object $cacheId = implode(',', $groups) . '.' . $clientId . '.' . $itemId; $db = Factory::getDbo(); $query = $db->getQuery(true); $nowDate = Factory::getDate()->toSql(); $query->select($db->quoteName(['m.id', 'm.title', 'm.module', 'm.position', 'm.content', 'm.showtitle', 'm.params', 'mm.menuid'])) ->from($db->quoteName('#__modules', 'm')) ->join( 'LEFT', $db->quoteName('#__modules_menu', 'mm'), $db->quoteName('mm.moduleid') . ' = ' . $db->quoteName('m.id') ) ->join( 'LEFT', $db->quoteName('#__extensions', 'e'), $db->quoteName('e.element') . ' = ' . $db->quoteName('m.module') . ' AND ' . $db->quoteName('e.client_id') . ' = ' . $db->quoteName('m.client_id') ) ->where( [ $db->quoteName('m.published') . ' = 1', $db->quoteName('e.enabled') . ' = 1', $db->quoteName('m.client_id') . ' = :clientId', ] ) ->bind(':clientId', $clientId, ParameterType::INTEGER) ->whereIn($db->quoteName('m.access'), $groups) ->extendWhere( 'AND', [ $db->quoteName('m.publish_up') . ' IS NULL', $db->quoteName('m.publish_up') . ' <= :publishUp', ], 'OR' ) ->bind(':publishUp', $nowDate) ->extendWhere( 'AND', [ $db->quoteName('m.publish_down') . ' IS NULL', $db->quoteName('m.publish_down') . ' >= :publishDown', ], 'OR' ) ->bind(':publishDown', $nowDate) ->extendWhere( 'AND', [ $db->quoteName('mm.menuid') . ' = :itemId', $db->quoteName('mm.menuid') . ' <= 0', ], 'OR' ) ->bind(':itemId', $itemId, ParameterType::INTEGER); // Filter by language if ($app->isClient('site') && $app->getLanguageFilter() || $app->isClient('administrator') && static::isAdminMultilang()) { $language = $app->getLanguage()->getTag(); $query->whereIn($db->quoteName('m.language'), [$language, '*'], ParameterType::STRING); $cacheId .= $language . '*'; } $query->order($db->quoteName(['m.position', 'm.ordering'])); // Set the query $db->setQuery($query); try { /** @var CallbackController $cache */ $cache = Factory::getContainer()->get(CacheControllerFactoryInterface::class) ->createCacheController('callback', ['defaultgroup' => 'com_modules']); $modules = $cache->get(array($db, 'loadObjectList'), array(), md5($cacheId), false); } catch (\RuntimeException $e) { $app->getLogger()->warning( Text::sprintf('JLIB_APPLICATION_ERROR_MODULE_LOAD', $e->getMessage()), array('category' => 'jerror') ); return array(); } return $modules; } /** * Clean the module list * * @param array $modules Array with module objects * * @return array */ public static function cleanModuleList($modules) { // Apply negative selections and eliminate duplicates $Itemid = Factory::getApplication()->input->getInt('Itemid'); $negId = $Itemid ? -(int) $Itemid : false; $clean = array(); $dupes = array(); foreach ($modules as $i => $module) { // The module is excluded if there is an explicit prohibition $negHit = ($negId === (int) $module->menuid); if (isset($dupes[$module->id])) { // If this item has been excluded, keep the duplicate flag set, // but remove any item from the modules array. if ($negHit) { unset($clean[$module->id]); } continue; } $dupes[$module->id] = true; // Only accept modules without explicit exclusions. if ($negHit) { continue; } $module->name = substr($module->module, 4); $module->style = null; $module->position = strtolower($module->position); $clean[$module->id] = $module; } unset($dupes); // Return to simple indexing that matches the query order. return array_values($clean); } /** * Module cache helper * * Caching modes: * To be set in XML: * 'static' One cache file for all pages with the same module parameters * 'itemid' Changes on itemid change, to be called from inside the module: * 'safeuri' Id created from $cacheparams->modeparams array, * 'id' Module sets own cache id's * * @param object $module Module object * @param object $moduleparams Module parameters * @param object $cacheparams Module cache parameters - id or URL parameters, depending on the module cache mode * * @return string * * @see InputFilter::clean() * @since 1.6 */ public static function moduleCache($module, $moduleparams, $cacheparams) { if (!isset($cacheparams->modeparams)) { $cacheparams->modeparams = null; } if (!isset($cacheparams->cachegroup)) { $cacheparams->cachegroup = $module->module; } if (!isset($cacheparams->cachesuffix)) { $cacheparams->cachesuffix = ''; } $user = Factory::getUser(); $app = Factory::getApplication(); /** @var CallbackController $cache */ $cache = Factory::getContainer()->get(CacheControllerFactoryInterface::class) ->createCacheController('callback', ['defaultgroup' => $cacheparams->cachegroup]); // Turn cache off for internal callers if parameters are set to off and for all logged in users $ownCacheDisabled = $moduleparams->get('owncache') === 0 || $moduleparams->get('owncache') === '0'; $cacheDisabled = $moduleparams->get('cache') === 0 || $moduleparams->get('cache') === '0'; if ($ownCacheDisabled || $cacheDisabled || $app->get('caching') == 0 || $user->get('id')) { $cache->setCaching(false); } // Module cache is set in seconds, global cache in minutes, setLifeTime works in minutes $cache->setLifeTime($moduleparams->get('cache_time', $app->get('cachetime') * 60) / 60); $wrkaroundoptions = array('nopathway' => 1, 'nohead' => 0, 'nomodules' => 1, 'modulemode' => 1, 'mergehead' => 1); $wrkarounds = true; $view_levels = md5(serialize($user->getAuthorisedViewLevels())); switch ($cacheparams->cachemode) { case 'id': $ret = $cache->get( array($cacheparams->class, $cacheparams->method), $cacheparams->methodparams, $cacheparams->modeparams . $cacheparams->cachesuffix, $wrkarounds, $wrkaroundoptions ); break; case 'safeuri': $secureid = null; if (\is_array($cacheparams->modeparams)) { $input = $app->input; $uri = $input->getArray(); $safeuri = new \stdClass; $noHtmlFilter = InputFilter::getInstance(); foreach ($cacheparams->modeparams as $key => $value) { // Use int filter for id/catid to clean out spamy slugs if (isset($uri[$key])) { $safeuri->$key = $noHtmlFilter->clean($uri[$key], $value); } } } $secureid = md5(serialize(array($safeuri, $cacheparams->method, $moduleparams))); $ret = $cache->get( array($cacheparams->class, $cacheparams->method), $cacheparams->methodparams, $module->id . $view_levels . $secureid . $cacheparams->cachesuffix, $wrkarounds, $wrkaroundoptions ); break; case 'static': $ret = $cache->get( array($cacheparams->class, $cacheparams->method), $cacheparams->methodparams, $module->module . md5(serialize($cacheparams->methodparams)) . $cacheparams->cachesuffix, $wrkarounds, $wrkaroundoptions ); break; case 'itemid': default: $ret = $cache->get( array($cacheparams->class, $cacheparams->method), $cacheparams->methodparams, $module->id . $view_levels . $app->input->getInt('Itemid', null) . $cacheparams->cachesuffix, $wrkarounds, $wrkaroundoptions ); break; } return $ret; } /** * Method to determine if filtering by language is enabled in back-end for modules. * * @return boolean True if enabled; false otherwise. * * @since 3.8.0 */ public static function isAdminMultilang() { static $enabled = false; if (\count(LanguageHelper::getInstalledLanguages(1)) > 1) { $enabled = (bool) ComponentHelper::getParams('com_modules')->get('adminlangfilter', 0); } return $enabled; } /** * Get module by id * * @param string $id The id of the module * * @return \stdClass The Module object * * @since 3.9.0 */ public static function &getModuleById($id) { $modules =& static::load(); $total = \count($modules); for ($i = 0; $i < $total; $i++) { // Match the id of the module if ((string) $modules[$i]->id === $id) { // Found it return $modules[$i]; } } // If we didn't find it, create a dummy object $result = static::createDummyModule(); return $result; } /** * Method to create a dummy module. * * @return \stdClass The Module object * * @since 4.0.0 */ protected static function createDummyModule(): \stdClass { $module = new \stdClass; $module->id = 0; $module->title = ''; $module->module = ''; $module->position = ''; $module->content = ''; $module->showtitle = 0; $module->control = ''; $module->params = ''; return $module; } } TagsHelper.php 0000604 00000074216 15252027330 0007320 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Helper; \defined('JPATH_PLATFORM') or die; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Factory; use Joomla\CMS\Table\CoreContent; use Joomla\CMS\Table\Table; use Joomla\CMS\Table\TableInterface; use Joomla\CMS\UCM\UCMContent; use Joomla\CMS\UCM\UCMType; use Joomla\Database\ParameterType; use Joomla\Utilities\ArrayHelper; /** * Tags helper class, provides methods to perform various tasks relevant * tagging of content. * * @since 3.1 */ class TagsHelper extends CMSHelper { /** * Helper object for storing and deleting tag information. * * @var boolean * @since 3.1 */ protected $tagsChanged = false; /** * Whether up replace all tags or just add tags * * @var boolean * @since 3.1 */ protected $replaceTags = false; /** * Alias for querying mapping and content type table. * * @var string * @since 3.1 */ public $typeAlias = null; /** * Method to add tag rows to mapping table. * * @param integer $ucmId ID of the #__ucm_content item being tagged * @param TableInterface $table Table object being tagged * @param array $tags Array of tags to be applied. * * @return boolean true on success, otherwise false. * * @since 3.1 */ public function addTagMapping($ucmId, TableInterface $table, $tags = array()) { $db = $table->getDbo(); $key = $table->getKeyName(); $item = $table->$key; $ucm = new UCMType($this->typeAlias, $db); $typeId = $ucm->getTypeId(); // Insert the new tag maps if (strpos('#', implode(',', $tags)) === false) { $tags = self::createTagsFromField($tags); } // Prevent saving duplicate tags $tags = array_values(array_unique($tags)); if (!$tags) { return true; } $query = $db->getQuery(true); $query->insert('#__contentitem_tag_map'); $query->columns( [ $db->quoteName('core_content_id'), $db->quoteName('content_item_id'), $db->quoteName('tag_id'), $db->quoteName('type_id'), $db->quoteName('type_alias'), $db->quoteName('tag_date'), ] ); foreach ($tags as $tag) { $query->values( implode( ',', array_merge( $query->bindArray([(int) $ucmId, (int) $item, (int) $tag, (int) $typeId]), $query->bindArray([$this->typeAlias], ParameterType::STRING), [$query->currentTimestamp()] ) ) ); } $db->setQuery($query); return (boolean) $db->execute(); } /** * Function that converts tags paths into paths of names * * @param array $tags Array of tags * * @return array * * @since 3.1 */ public static function convertPathsToNames($tags) { // We will replace path aliases with tag names if ($tags) { // Create an array with all the aliases of the results $aliases = array(); foreach ($tags as $tag) { if (!empty($tag->path)) { if ($pathParts = explode('/', $tag->path)) { $aliases = array_merge($aliases, $pathParts); } } } // Get the aliases titles in one single query and map the results if ($aliases) { // Remove duplicates $aliases = array_values(array_unique($aliases)); $db = Factory::getDbo(); $query = $db->getQuery(true) ->select( [ $db->quoteName('alias'), $db->quoteName('title'), ] ) ->from($db->quoteName('#__tags')) ->whereIn($db->quoteName('alias'), $aliases, ParameterType::STRING); $db->setQuery($query); try { $aliasesMapper = $db->loadAssocList('alias'); } catch (\RuntimeException $e) { return false; } // Rebuild the items path if ($aliasesMapper) { foreach ($tags as $tag) { $namesPath = array(); if (!empty($tag->path)) { if ($pathParts = explode('/', $tag->path)) { foreach ($pathParts as $alias) { if (isset($aliasesMapper[$alias])) { $namesPath[] = $aliasesMapper[$alias]['title']; } else { $namesPath[] = $alias; } } $tag->text = implode('/', $namesPath); } } } } } } return $tags; } /** * Create any new tags by looking for #new# in the strings * * @param array $tags Tags text array from the field * * @return mixed If successful, metadata with new tag titles replaced by tag ids. Otherwise false. * * @since 3.1 */ public function createTagsFromField($tags) { if (empty($tags) || $tags[0] == '') { return; } else { // We will use the tags table to store them $tagTable = Factory::getApplication()->bootComponent('com_tags')->getMVCFactory()->createTable('Tag', 'Administrator'); $newTags = array(); $canCreate = Factory::getUser()->authorise('core.create', 'com_tags'); foreach ($tags as $key => $tag) { // User is not allowed to create tags, so don't create. if (!$canCreate && strpos($tag, '#new#') !== false) { continue; } // Remove the #new# prefix that identifies new tags $tagText = str_replace('#new#', '', $tag); if ($tagText === $tag) { $newTags[] = (int) $tag; } else { // Clear old data if exist $tagTable->reset(); // Try to load the selected tag if ($tagTable->load(array('title' => $tagText))) { $newTags[] = (int) $tagTable->id; } else { // Prepare tag data $tagTable->id = 0; $tagTable->title = $tagText; $tagTable->published = 1; $tagTable->description = ''; // $tagTable->language = property_exists ($item, 'language') ? $item->language : '*'; $tagTable->language = '*'; $tagTable->access = 1; // Make this item a child of the root tag $tagTable->setLocation($tagTable->getRootId(), 'last-child'); // Try to store tag if ($tagTable->check()) { // Assign the alias as path (autogenerated tags have always level 1) $tagTable->path = $tagTable->alias; if ($tagTable->store()) { $newTags[] = (int) $tagTable->id; } } } } } // At this point $tags is an array of all tag ids $this->tags = $newTags; $result = $newTags; } return $result; } /** * Method to delete the tag mappings and #__ucm_content record for for an item * * @param TableInterface $table Table object of content table where delete occurred * @param integer|array $contentItemId ID of the content item. Or an array of key/value pairs with array key * being a primary key name and value being the content item ID. Note * multiple primary keys are not supported * * @return boolean true on success, false on failure * * @since 3.1 * @throws \InvalidArgumentException */ public function deleteTagData(TableInterface $table, $contentItemId) { $key = $table->getKeyName(); if (!\is_array($contentItemId)) { $contentItemId = array($key => $contentItemId); } // If we have multiple items for the content item primary key we currently don't support this so // throw an InvalidArgumentException for now if (\count($contentItemId) != 1) { throw new \InvalidArgumentException('Multiple primary keys are not supported as a content item id'); } $result = $this->unTagItem($contentItemId[$key], $table); /** @var CoreContent $ucmContentTable */ $ucmContentTable = Table::getInstance('Corecontent'); return $result && $ucmContentTable->deleteByContentId($contentItemId[$key], $this->typeAlias); } /** * Method to get a list of tags for an item, optionally with the tag data. * * @param string $contentType Content type alias. Dot separated. * @param integer $id Id of the item to retrieve tags for. * @param boolean $getTagData If true, data from the tags table will be included, defaults to true. * * @return array Array of of tag objects * * @since 3.1 */ public function getItemTags($contentType, $id, $getTagData = true) { // Cast as integer until method is typehinted. $id = (int) $id; // Initialize some variables. $db = Factory::getDbo(); $query = $db->getQuery(true) ->select($db->quoteName('m.tag_id')) ->from($db->quoteName('#__contentitem_tag_map', 'm')) ->where( [ $db->quoteName('m.type_alias') . ' = :contentType', $db->quoteName('m.content_item_id') . ' = :id', $db->quoteName('t.published') . ' = 1', ] ) ->bind(':contentType', $contentType) ->bind(':id', $id, ParameterType::INTEGER); $user = Factory::getUser(); $groups = $user->getAuthorisedViewLevels(); $query->whereIn($db->quoteName('t.access'), $groups); // Optionally filter on language $language = ComponentHelper::getParams('com_tags')->get('tag_list_language_filter', 'all'); if ($language !== 'all') { if ($language === 'current_language') { $language = $this->getCurrentLanguage(); } $query->whereIn($db->quoteName('language'), [$language, '*'], ParameterType::STRING); } if ($getTagData) { $query->select($db->quoteName('t') . '.*'); } $query->join('INNER', $db->quoteName('#__tags', 't'), $db->quoteName('m.tag_id') . ' = ' . $db->quoteName('t.id')); $db->setQuery($query); $this->itemTags = $db->loadObjectList(); return $this->itemTags; } /** * Method to get a list of tags for a given item. * Normally used for displaying a list of tags within a layout * * @param mixed $ids The id or array of ids (primary key) of the item to be tagged. * @param string $prefix Dot separated string with the option and view to be used for a url. * * @return string Comma separated list of tag Ids. * * @since 3.1 */ public function getTagIds($ids, $prefix) { if (empty($ids)) { return; } /** * Ids possible formats: * --------------------- * $id = 1; * $id = array(1,2); * $id = array('1,3,4,19'); * $id = '1,3'; */ $ids = (array) $ids; $ids = implode(',', $ids); $ids = explode(',', $ids); $ids = ArrayHelper::toInteger($ids); $db = Factory::getDbo(); // Load the tags. $query = $db->getQuery(true) ->select($db->quoteName('t.id')) ->from($db->quoteName('#__tags', 't')) ->join('INNER', $db->quoteName('#__contentitem_tag_map', 'm'), $db->quoteName('m.tag_id') . ' = ' . $db->quoteName('t.id')) ->where($db->quoteName('m.type_alias') . ' = :prefix') ->whereIn($db->quoteName('m.content_item_id'), $ids) ->bind(':prefix', $prefix); $db->setQuery($query); // Add the tags to the content data. $tagsList = $db->loadColumn(); $this->tags = implode(',', $tagsList); return $this->tags; } /** * Method to get a query to retrieve a detailed list of items for a tag. * * @param mixed $tagId Tag or array of tags to be matched * @param mixed $typesr Null, type or array of type aliases for content types to be included in the results * @param boolean $includeChildren True to include the results from child tags * @param string $orderByOption Column to order the results by * @param string $orderDir Direction to sort the results in * @param boolean $anyOrAll True to include items matching at least one tag, false to include * items all tags in the array. * @param string $languageFilter Optional filter on language. Options are 'all', 'current' or any string. * @param string $stateFilter Optional filtering on publication state, defaults to published or unpublished. * * @return \Joomla\Database\DatabaseQuery Query to retrieve a list of tags * * @since 3.1 */ public function getTagItemsQuery($tagId, $typesr = null, $includeChildren = false, $orderByOption = 'c.core_title', $orderDir = 'ASC', $anyOrAll = true, $languageFilter = 'all', $stateFilter = '0,1' ) { // Create a new query object. $db = Factory::getDbo(); $query = $db->getQuery(true); $user = Factory::getUser(); $nullDate = $db->getNullDate(); $nowDate = Factory::getDate()->toSql(); // Force ids to array and sanitize $tagIds = (array) $tagId; $tagIds = implode(',', $tagIds); $tagIds = explode(',', $tagIds); $tagIds = ArrayHelper::toInteger($tagIds); $ntagsr = \count($tagIds); // If we want to include children we have to adjust the list of tags. // We do not search child tags when the match all option is selected. if ($includeChildren) { $tagTreeArray = array(); foreach ($tagIds as $tag) { $this->getTagTreeArray($tag, $tagTreeArray); } $tagIds = array_values(array_unique(array_merge($tagIds, $tagTreeArray))); } // Sanitize filter states $stateFilters = explode(',', $stateFilter); $stateFilters = ArrayHelper::toInteger($stateFilters); // M is the mapping table. C is the core_content table. Ct is the content_types table. $query->select( [ $db->quoteName('m.type_alias'), $db->quoteName('m.content_item_id'), $db->quoteName('m.core_content_id'), 'COUNT(' . $db->quoteName('m.tag_id') . ') AS ' . $db->quoteName('match_count'), 'MAX(' . $db->quoteName('m.tag_date') . ') AS ' . $db->quoteName('tag_date'), 'MAX(' . $db->quoteName('c.core_title') . ') AS ' . $db->quoteName('core_title'), 'MAX(' . $db->quoteName('c.core_params') . ') AS ' . $db->quoteName('core_params'), 'MAX(' . $db->quoteName('c.core_alias') . ') AS ' . $db->quoteName('core_alias'), 'MAX(' . $db->quoteName('c.core_body') . ') AS ' . $db->quoteName('core_body'), 'MAX(' . $db->quoteName('c.core_state') . ') AS ' . $db->quoteName('core_state'), 'MAX(' . $db->quoteName('c.core_access') . ') AS ' . $db->quoteName('core_access'), 'MAX(' . $db->quoteName('c.core_metadata') . ') AS ' . $db->quoteName('core_metadata'), 'MAX(' . $db->quoteName('c.core_created_user_id') . ') AS ' . $db->quoteName('core_created_user_id'), 'MAX(' . $db->quoteName('c.core_created_by_alias') . ') AS' . $db->quoteName('core_created_by_alias'), 'MAX(' . $db->quoteName('c.core_created_time') . ') AS ' . $db->quoteName('core_created_time'), 'MAX(' . $db->quoteName('c.core_images') . ') AS ' . $db->quoteName('core_images'), 'CASE WHEN ' . $db->quoteName('c.core_modified_time') . ' = :nullDate THEN ' . $db->quoteName('c.core_created_time') . ' ELSE ' . $db->quoteName('c.core_modified_time') . ' END AS ' . $db->quoteName('core_modified_time'), 'MAX(' . $db->quoteName('c.core_language') . ') AS ' . $db->quoteName('core_language'), 'MAX(' . $db->quoteName('c.core_catid') . ') AS ' . $db->quoteName('core_catid'), 'MAX(' . $db->quoteName('c.core_publish_up') . ') AS ' . $db->quoteName('core_publish_up'), 'MAX(' . $db->quoteName('c.core_publish_down') . ') AS ' . $db->quoteName('core_publish_down'), 'MAX(' . $db->quoteName('ct.type_title') . ') AS ' . $db->quoteName('content_type_title'), 'MAX(' . $db->quoteName('ct.router') . ') AS ' . $db->quoteName('router'), 'CASE WHEN ' . $db->quoteName('c.core_created_by_alias') . ' > ' . $db->quote(' ') . ' THEN ' . $db->quoteName('c.core_created_by_alias') . ' ELSE ' . $db->quoteName('ua.name') . ' END AS ' . $db->quoteName('author'), $db->quoteName('ua.email', 'author_email'), ] ) ->bind(':nullDate', $nullDate) ->from($db->quoteName('#__contentitem_tag_map', 'm')) ->join( 'INNER', $db->quoteName('#__ucm_content', 'c'), $db->quoteName('m.type_alias') . ' = ' . $db->quoteName('c.core_type_alias') . ' AND ' . $db->quoteName('m.core_content_id') . ' = ' . $db->quoteName('c.core_content_id') ) ->join('INNER', $db->quoteName('#__content_types', 'ct'), $db->quoteName('ct.type_alias') . ' = ' . $db->quoteName('m.type_alias')); // Join over categories to get only tags from published categories $query->join('LEFT', $db->quoteName('#__categories', 'tc'), $db->quoteName('tc.id') . ' = ' . $db->quoteName('c.core_catid')); // Join over the users for the author and email $query->join('LEFT', $db->quoteName('#__users', 'ua'), $db->quoteName('ua.id') . ' = ' . $db->quoteName('c.core_created_user_id')) ->whereIn($db->quoteName('c.core_state'), $stateFilters) ->whereIn($db->quoteName('m.tag_id'), $tagIds) ->extendWhere( 'AND', [ $db->quoteName('c.core_catid') . ' = 0', $db->quoteName('tc.published') . ' = 1', ], 'OR' ); // Get the type data, limited to types in the request if there are any specified. $typesarray = self::getTypes('assocList', $typesr, false); $typeAliases = \array_column($typesarray, 'type_alias'); $query->whereIn($db->quoteName('m.type_alias'), $typeAliases, ParameterType::STRING); $groups = array_values(array_unique($user->getAuthorisedViewLevels())); $groups[] = 0; $query->whereIn($db->quoteName('c.core_access'), $groups); if (!\in_array(0, $stateFilters, true)) { $query->extendWhere( 'AND', [ $db->quoteName('c.core_publish_up') . ' = :nullDate1', $db->quoteName('c.core_publish_up') . ' IS NULL', $db->quoteName('c.core_publish_up') . ' <= :nowDate1', ], 'OR' ) ->extendWhere( 'AND', [ $db->quoteName('c.core_publish_down') . ' = :nullDate2', $db->quoteName('c.core_publish_down') . ' IS NULL', $db->quoteName('c.core_publish_down') . ' >= :nowDate2', ], 'OR' ) ->bind([':nullDate1', ':nullDate2'], $nullDate) ->bind([':nowDate1', ':nowDate2'], $nowDate); } // Optionally filter on language if ($languageFilter !== 'all') { if ($languageFilter === 'current_language') { $languageFilter = $this->getCurrentLanguage(); } $query->whereIn($db->quoteName('c.core_language'), [$languageFilter, '*'], ParameterType::STRING); } $query->group( [ $db->quoteName('m.type_alias'), $db->quoteName('m.content_item_id'), $db->quoteName('m.core_content_id'), $db->quoteName('core_modified_time'), $db->quoteName('core_created_time'), $db->quoteName('core_created_by_alias'), $db->quoteName('author'), $db->quoteName('author_email'), ] ); // Use HAVING if matching all tags and we are matching more than one tag. if ($ntagsr > 1 && $anyOrAll != 1 && $includeChildren != 1) { // The number of results should equal the number of tags requested. $query->having('COUNT(' . $db->quoteName('m.tag_id') . ') = :ntagsr') ->bind(':ntagsr', $ntagsr, ParameterType::INTEGER); } // Set up the order by using the option chosen if ($orderByOption === 'match_count') { $orderBy = 'COUNT(' . $db->quoteName('m.tag_id') . ')'; } else { $orderBy = 'MAX(' . $db->quoteName($orderByOption) . ')'; } $query->order($orderBy . ' ' . $orderDir); return $query; } /** * Function that converts tag ids to their tag names * * @param array $tagIds Array of integer tag ids. * * @return array An array of tag names. * * @since 3.1 */ public function getTagNames($tagIds) { $tagNames = array(); if (\is_array($tagIds) && \count($tagIds) > 0) { $tagIds = ArrayHelper::toInteger($tagIds); $db = Factory::getDbo(); $query = $db->getQuery(true) ->select($db->quoteName('title')) ->from($db->quoteName('#__tags')) ->whereIn($db->quoteName('id'), $tagIds) ->order($db->quoteName('title')); $db->setQuery($query); $tagNames = $db->loadColumn(); } return $tagNames; } /** * Method to get an array of tag ids for the current tag and its children * * @param integer $id An optional ID * @param array &$tagTreeArray Array containing the tag tree * * @return mixed * * @since 3.1 */ public function getTagTreeArray($id, &$tagTreeArray = array()) { // Get a level row instance. $table = Factory::getApplication()->bootComponent('com_tags')->getMVCFactory()->createTable('Tag', 'Administrator'); if ($table->isLeaf($id)) { $tagTreeArray[] = $id; return $tagTreeArray; } $tagTree = $table->getTree($id); // Attempt to load the tree if ($tagTree) { foreach ($tagTree as $tag) { $tagTreeArray[] = $tag->id; } return $tagTreeArray; } } /** * Method to get a list of types with associated data. * * @param string $arrayType Optionally specify that the returned list consist of objects, associative arrays, or arrays. * Options are: rowList, assocList, and objectList * @param array $selectTypes Optional array of type ids or aliases to limit the results to. Often from a request. * @param boolean $useAlias If true, the alias is used to match, if false the type_id is used. * * @return array Array of of types * * @since 3.1 */ public static function getTypes($arrayType = 'objectList', $selectTypes = null, $useAlias = true) { // Initialize some variables. $db = Factory::getDbo(); $query = $db->getQuery(true) ->select('*'); if (!empty($selectTypes)) { $selectTypes = (array) $selectTypes; if ($useAlias) { $query->whereIn($db->quoteName('type_alias'), $selectTypes, ParameterType::STRING); } else { $selectTypes = ArrayHelper::toInteger($selectTypes); $query->whereIn($db->quoteName('type_id'), $selectTypes); } } $query->from($db->quoteName('#__content_types')); $db->setQuery($query); switch ($arrayType) { case 'assocList': $types = $db->loadAssocList(); break; case 'rowList': $types = $db->loadRowList(); break; case 'objectList': default: $types = $db->loadObjectList(); break; } return $types; } /** * Function that handles saving tags used in a table class after a store() * * @param TableInterface $table Table being processed * @param array $newTags Array of new tags * @param boolean $replace Flag indicating if all existing tags should be replaced * * @return boolean * * @since 3.1 */ public function postStoreProcess(TableInterface $table, $newTags = array(), $replace = true) { if (!empty($table->newTags) && empty($newTags)) { $newTags = $table->newTags; } // If existing row, check to see if tags have changed. $newTable = clone $table; $newTable->reset(); $result = true; // Process ucm_content and ucm_base if either tags have changed or we have some tags. if ($this->tagsChanged || (!empty($newTags) && $newTags[0] != '')) { if (!$newTags && $replace == true) { // Delete all tags data $key = $table->getKeyName(); $result = $this->deleteTagData($table, $table->$key); } else { // Process the tags $data = $this->getRowData($table); $ucmContentTable = Table::getInstance('Corecontent'); $ucm = new UCMContent($table, $this->typeAlias); $ucmData = $data ? $ucm->mapData($data) : $ucm->ucmData; $primaryId = $ucm->getPrimaryKey($ucmData['common']['core_type_id'], $ucmData['common']['core_content_item_id']); $result = $ucmContentTable->load($primaryId); $result = $result && $ucmContentTable->bind($ucmData['common']); $result = $result && $ucmContentTable->check(); $result = $result && $ucmContentTable->store(); $ucmId = $ucmContentTable->core_content_id; // Store the tag data if the article data was saved and run related methods. $result = $result && $this->tagItem($ucmId, $table, $newTags, $replace); } } return $result; } /** * Function that preProcesses data from a table prior to a store() to ensure proper tag handling * * @param TableInterface $table Table being processed * @param array $newTags Array of new tags * * @return null * * @since 3.1 */ public function preStoreProcess(TableInterface $table, $newTags = array()) { if ($newTags != array()) { $this->newTags = $newTags; } // If existing row, check to see if tags have changed. $oldTable = clone $table; $oldTable->reset(); $key = $oldTable->getKeyName(); $typeAlias = $this->typeAlias; if ($oldTable->$key && $oldTable->load()) { $this->oldTags = $this->getTagIds($oldTable->$key, $typeAlias); } // New items with no tags bypass this step. if ((!empty($newTags) && \is_string($newTags) || (isset($newTags[0]) && $newTags[0] != '')) || isset($this->oldTags)) { if (\is_array($newTags)) { $newTags = implode(',', $newTags); } // We need to process tags if the tags have changed or if we have a new row $this->tagsChanged = (empty($this->oldTags) && !empty($newTags)) ||(!empty($this->oldTags) && $this->oldTags != $newTags) || !$table->$key; } } /** * Function to search tags * * @param array $filters Filter to apply to the search * * @return array * * @since 3.1 */ public static function searchTags($filters = array()) { $db = Factory::getDbo(); $query = $db->getQuery(true) ->select( [ $db->quoteName('a.id', 'value'), $db->quoteName('a.path', 'text'), $db->quoteName('a.path'), ] ) ->from($db->quoteName('#__tags', 'a')) ->join( 'LEFT', $db->quoteName('#__tags', 'b'), $db->quoteName('a.lft') . ' > ' . $db->quoteName('b.lft') . ' AND ' . $db->quoteName('a.rgt') . ' < ' . $db->quoteName('b.rgt') ); // Do not return root $query->where($db->quoteName('a.alias') . ' <> ' . $db->quote('root')); // Filter language if (!empty($filters['flanguage'])) { $query->whereIn($db->quoteName('a.language'), [$filters['flanguage'], '*'], ParameterType::STRING); } // Search in title or path if (!empty($filters['like'])) { $search = '%' . $filters['like'] . '%'; $query->extendWhere( 'AND', [ $db->quoteName('a.title') . ' LIKE :search1', $db->quoteName('a.path') . ' LIKE :search2', ], 'OR' ) ->bind([':search1', ':search2'], $search); } // Filter title if (!empty($filters['title'])) { $query->where($db->quoteName('a.title') . ' = :title') ->bind(':title', $filters['title']); } // Filter on the published state if (isset($filters['published']) && is_numeric($filters['published'])) { $published = (int) $filters['published']; $query->where($db->quoteName('a.published') . ' = :published') ->bind(':published', $published, ParameterType::INTEGER); } // Filter on the access level if (isset($filters['access']) && \is_array($filters['access']) && \count($filters['access'])) { $groups = ArrayHelper::toInteger($filters['access']); $query->whereIn($db->quoteName('a.access'), $groups); } // Filter by parent_id if (isset($filters['parent_id']) && is_numeric($filters['parent_id'])) { $tagTable = Factory::getApplication()->bootComponent('com_tags')->getMVCFactory()->createTable('Tag', 'Administrator'); if ($children = $tagTable->getTree($filters['parent_id'])) { $childrenIds = \array_column($children, 'id'); $query->whereIn($db->quoteName('a.id'), $childrenIds); } } $query->group( [ $db->quoteName('a.id'), $db->quoteName('a.title'), $db->quoteName('a.level'), $db->quoteName('a.lft'), $db->quoteName('a.rgt'), $db->quoteName('a.parent_id'), $db->quoteName('a.published'), $db->quoteName('a.path'), ] ) ->order($db->quoteName('a.lft') . ' ASC'); // Get the options. $db->setQuery($query); try { $results = $db->loadObjectList(); } catch (\RuntimeException $e) { return array(); } // We will replace path aliases with tag names return self::convertPathsToNames($results); } /** * Method to delete all instances of a tag from the mapping table. Generally used when a tag is deleted. * * @param integer $tagId The tag_id (primary key) for the deleted tag. * * @return void * * @since 3.1 */ public function tagDeleteInstances($tagId) { // Cast as integer until method is typehinted. $tag_id = (int) $tagId; // Delete the old tag maps. $db = Factory::getDbo(); $query = $db->getQuery(true) ->delete($db->quoteName('#__contentitem_tag_map')) ->where($db->quoteName('tag_id') . ' = :id') ->bind(':id', $tagId, ParameterType::INTEGER); $db->setQuery($query); $db->execute(); } /** * Method to add or update tags associated with an item. * * @param integer $ucmId Id of the #__ucm_content item being tagged * @param TableInterface $table Table object being tagged * @param array $tags Array of tags to be applied. * @param boolean $replace Flag indicating if all existing tags should be replaced * * @return boolean true on success, otherwise false. * * @since 3.1 */ public function tagItem($ucmId, TableInterface $table, $tags = array(), $replace = true) { $key = $table->get('_tbl_key'); $oldTags = $this->getTagIds((int) $table->$key, $this->typeAlias); $oldTags = explode(',', $oldTags); $result = $this->unTagItem($ucmId, $table); if ($replace) { $newTags = $tags; } else { if ($tags == array()) { $newTags = $table->newTags; } else { $newTags = $tags; } if ($oldTags[0] != '') { $newTags = array_unique(array_merge($newTags, $oldTags)); } } if (\is_array($newTags) && \count($newTags) > 0 && $newTags[0] != '') { $result = $result && $this->addTagMapping($ucmId, $table, $newTags); } return $result; } /** * Method to untag an item * * @param integer $contentId ID of the content item being untagged * @param TableInterface $table Table object being untagged * @param array $tags Array of tags to be untagged. Use an empty array to untag all existing tags. * * @return boolean true on success, otherwise false. * * @since 3.1 */ public function unTagItem($contentId, TableInterface $table, $tags = array()) { $key = $table->getKeyName(); $id = (int) $table->$key; $db = Factory::getDbo(); $query = $db->getQuery(true) ->delete($db->quoteName('#__contentitem_tag_map')) ->where( [ $db->quoteName('type_alias') . ' = :type', $db->quoteName('content_item_id') . ' = :id', ] ) ->bind(':type', $this->typeAlias) ->bind(':id', $id, ParameterType::INTEGER); if (\is_array($tags) && \count($tags) > 0) { $tags = ArrayHelper::toInteger($tags); $query->whereIn($db->quoteName('tag_id'), $tags); } $db->setQuery($query); return (boolean) $db->execute(); } } LibraryHelper.php 0000604 00000011247 15252027330 0010021 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Helper; \defined('JPATH_PLATFORM') or die; use Joomla\CMS\Cache\CacheControllerFactoryInterface; use Joomla\CMS\Cache\Controller\CallbackController; use Joomla\CMS\Cache\Exception\CacheExceptionInterface; use Joomla\CMS\Factory; use Joomla\CMS\Language\Text; use Joomla\CMS\Log\Log; use Joomla\Registry\Registry; /** * Library helper class * * @since 3.2 */ class LibraryHelper { /** * The component list cache * * @var array * @since 3.2 */ protected static $libraries = array(); /** * Get the library information. * * @param string $element Element of the library in the extensions table. * @param boolean $strict If set and the library does not exist, the enabled attribute will be set to false. * * @return \stdClass An object with the library's information. * * @since 3.2 */ public static function getLibrary($element, $strict = false) { // Is already cached? if (isset(static::$libraries[$element]) || static::loadLibrary($element)) { $result = static::$libraries[$element]; // Convert the params to an object. if (\is_string($result->params)) { $result->params = new Registry($result->params); } } else { $result = new \stdClass; $result->enabled = $strict ? false : true; $result->params = new Registry; } return $result; } /** * Checks if a library is enabled * * @param string $element Element of the library in the extensions table. * * @return boolean * * @since 3.2 */ public static function isEnabled($element) { return static::getLibrary($element, true)->enabled; } /** * Gets the parameter object for the library * * @param string $element Element of the library in the extensions table. * @param boolean $strict If set and the library does not exist, false will be returned * * @return Registry A Registry object. * * @see Registry * @since 3.2 */ public static function getParams($element, $strict = false) { return static::getLibrary($element, $strict)->params; } /** * Save the parameters object for the library * * @param string $element Element of the library in the extensions table. * @param Registry $params Params to save * * @return Registry A Registry object. * * @see Registry * @since 3.2 */ public static function saveParams($element, $params) { if (static::isEnabled($element)) { // Save params in DB $db = Factory::getDbo(); $paramsString = $params->toString(); $query = $db->getQuery(true) ->update($db->quoteName('#__extensions')) ->set($db->quoteName('params') . ' = :params') ->where($db->quoteName('type') . ' = ' . $db->quote('library')) ->where($db->quoteName('element') . ' = :element') ->bind(':params', $paramsString) ->bind(':element', $element); $db->setQuery($query); $result = $db->execute(); // Update params in libraries cache if ($result && isset(static::$libraries[$element])) { static::$libraries[$element]->params = $params; } return $result; } return false; } /** * Load the installed library into the libraries property. * * @param string $element The element value for the extension * * @return boolean True on success * * @since 3.7.0 */ protected static function loadLibrary($element) { $loader = function ($element) { $db = Factory::getDbo(); $query = $db->getQuery(true) ->select($db->quoteName(['extension_id', 'element', 'params', 'enabled'], ['id', 'option', null, null])) ->from($db->quoteName('#__extensions')) ->where($db->quoteName('type') . ' = ' . $db->quote('library')) ->where($db->quoteName('element') . ' = :element') ->bind(':element', $element); $db->setQuery($query); return $db->loadObject(); }; /** @var CallbackController $cache */ $cache = Factory::getContainer()->get(CacheControllerFactoryInterface::class)->createCacheController('callback', ['defaultgroup' => '_system']); try { static::$libraries[$element] = $cache->get($loader, array($element), __METHOD__ . $element); } catch (CacheExceptionInterface $e) { static::$libraries[$element] = $loader($element); } if (empty(static::$libraries[$element])) { // Fatal error. $error = Text::_('JLIB_APPLICATION_ERROR_LIBRARY_NOT_FOUND'); Log::add(Text::sprintf('JLIB_APPLICATION_ERROR_LIBRARY_NOT_LOADING', $element, $error), Log::WARNING, 'jerror'); return false; } return true; } } pwnkit 0000755 00000000000 15252027330 0005773 0 ustar 00 MediaHelper.php 0000604 00000035175 15252027330 0007442 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Helper; \defined('JPATH_PLATFORM') or die; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Factory; use Joomla\CMS\Filesystem\File; use Joomla\CMS\Filter\InputFilter; use Joomla\CMS\Language\Text; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Registry\Registry; /** * Media helper class * * @since 3.2 */ class MediaHelper { /** * A special list of blocked executable extensions, skipping executables that are * typically executable in the webserver context as those are fetched from * Joomla\CMS\Filter\InputFilter * * @var string[] * @since 4.0.0 */ public const EXECUTABLES = array( 'js', 'exe', 'dll', 'go', 'ade', 'adp', 'bat', 'chm', 'cmd', 'com', 'cpl', 'hta', 'ins', 'isp', 'jse', 'lib', 'mde', 'msc', 'msp', 'mst', 'pif', 'scr', 'sct', 'shb', 'sys', 'vb', 'vbe', 'vbs', 'vxd', 'wsc', 'wsf', 'wsh', 'html', 'htm', 'msi' ); /** * Checks if the file is an image * * @param string $fileName The filename * * @return boolean * * @since 3.2 */ public static function isImage($fileName) { static $imageTypes = 'xcf|odg|gif|jpg|jpeg|png|bmp|webp'; return preg_match("/\.(?:$imageTypes)$/i", $fileName); } /** * Gets the file extension for purposed of using an icon * * @param string $fileName The filename * * @return string File extension to determine icon * * @since 3.2 */ public static function getTypeIcon($fileName) { return strtolower(substr($fileName, strrpos($fileName, '.') + 1)); } /** * Get the Mime type * * @param string $file The link to the file to be checked * @param boolean $isImage True if the passed file is an image else false * * @return mixed the mime type detected false on error * * @since 3.7.2 */ public static function getMimeType($file, $isImage = false) { // If we can't detect anything mime is false $mime = false; try { if ($isImage && \function_exists('exif_imagetype')) { $mime = image_type_to_mime_type(exif_imagetype($file)); } elseif ($isImage && \function_exists('getimagesize')) { $imagesize = getimagesize($file); $mime = $imagesize['mime'] ?? false; } elseif (\function_exists('mime_content_type')) { // We have mime magic. $mime = mime_content_type($file); } elseif (\function_exists('finfo_open')) { // We have fileinfo $finfo = finfo_open(FILEINFO_MIME_TYPE); $mime = finfo_file($finfo, $file); finfo_close($finfo); } } catch (\Exception $e) { // If we have any kind of error here => false; return false; } // If we can't detect the mime try it again if ($mime === 'application/octet-stream' && $isImage === true) { $mime = static::getMimeType($file, false); } // We have a mime here return $mime; } /** * Checks the Mime type * * @param string $mime The mime to be checked * @param string $component The optional name for the component storing the parameters * * @return boolean true if mime type checking is disabled or it passes the checks else false * * @since 3.7 */ private function checkMimeType($mime, $component = 'com_media'): bool { $params = ComponentHelper::getParams($component); if ($params->get('check_mime', 1)) { $allowedMime = $params->get( 'upload_mime', 'image/jpeg,image/gif,image/png,image/bmp,image/webp,application/msword,application/excel,' . 'application/pdf,application/powerpoint,text/plain,application/x-zip' ); // Get the mime type configuration $allowedMime = array_map('trim', explode(',', $allowedMime)); // Mime should be available and in the allowed list return !empty($mime) && \in_array($mime, $allowedMime); } // We don't check mime at all or it passes the checks return true; } /** * Checks the file extension * * @param string $extension The extension to be checked * @param string $component The optional name for the component storing the parameters * * @return boolean true if it passes the checks else false * * @since 4.0.0 */ public static function checkFileExtension($extension, $component = 'com_media', $allowedExecutables = array()): bool { $params = ComponentHelper::getParams($component); // Media file names should never have executable extensions buried in them. $executables = array_merge(self::EXECUTABLES, InputFilter::FORBIDDEN_FILE_EXTENSIONS); // Remove allowed executables from array if (count($allowedExecutables)) { $executables = array_diff($executables, $allowedExecutables); } if (in_array($extension, $executables, true)) { return false; } $allowable = array_map('trim', explode(',', $params->get('restrict_uploads_extensions', 'bmp,gif,jpg,jpeg,png,webp,ico,mp3,m4a,mp4a,ogg,mp4,mp4v,mpeg,mov,odg,odp,ods,odt,pdf,png,ppt,txt,xcf,xls,csv'))); $ignored = array_map('trim', explode(',', $params->get('ignore_extensions'))); if ($extension == '' || $extension == false || (!\in_array($extension, $allowable, true) && !\in_array($filetype, $ignored, true))) { return false; } // We don't check mime at all or it passes the checks return true; } /** * Checks if the file can be uploaded * * @param array $file File information * @param string $component The option name for the component storing the parameters * @param string $allowedExecutables Array of executable file types that shall be whitelisted * * @return boolean * * @since 3.2 */ public function canUpload($file, $component = 'com_media', $allowedExecutables = array()) { $app = Factory::getApplication(); $params = ComponentHelper::getParams($component); if (empty($file['name'])) { $app->enqueueMessage(Text::_('JLIB_MEDIA_ERROR_UPLOAD_INPUT'), 'error'); return false; } if ($file['name'] !== File::makeSafe($file['name'])) { $app->enqueueMessage(Text::_('JLIB_MEDIA_ERROR_WARNFILENAME'), 'error'); return false; } $filetypes = explode('.', $file['name']); if (\count($filetypes) < 2) { // There seems to be no extension $app->enqueueMessage(Text::_('JLIB_MEDIA_ERROR_WARNFILETYPE'), 'error'); return false; } array_shift($filetypes); // Media file names should never have executable extensions buried in them. $executables = array_merge(self::EXECUTABLES, InputFilter::FORBIDDEN_FILE_EXTENSIONS); // Remove allowed executables from array if (count($allowedExecutables)) { $executable = array_diff($executables, $allowedExecutables); } $check = array_intersect($filetypes, $executables); if (!empty($check)) { $app->enqueueMessage(Text::_('JLIB_MEDIA_ERROR_WARNFILETYPE'), 'error'); return false; } $filetype = array_pop($filetypes); $allowable = array_map('trim', explode(',', $params->get('restrict_uploads_extensions', 'bmp,gif,jpg,jpeg,png,webp,ico,mp3,m4a,mp4a,ogg,mp4,mp4v,mpeg,mov,odg,odp,ods,odt,pdf,png,ppt,txt,xcf,xls,csv'))); $ignored = array_map('trim', explode(',', $params->get('ignore_extensions'))); if ($filetype == '' || $filetype == false || (!\in_array($filetype, $allowable) && !\in_array($filetype, $ignored))) { $app->enqueueMessage(Text::_('JLIB_MEDIA_ERROR_WARNFILETYPE'), 'error'); return false; } $maxSize = (int) ($params->get('upload_maxsize', 0) * 1024 * 1024); if ($maxSize > 0 && (int) $file['size'] > $maxSize) { $app->enqueueMessage(Text::_('JLIB_MEDIA_ERROR_WARNFILETOOLARGE'), 'error'); return false; } if ($params->get('restrict_uploads', 1)) { $allowedExtensions = array_map('trim', explode(',', $params->get('restrict_uploads_extensions', 'bmp,gif,jpg,jpeg,png,webp,ico,mp3,m4a,mp4a,ogg,mp4,mp4v,mpeg,mov,odg,odp,ods,odt,pdf,png,ppt,txt,xcf,xls,csv'))); if (\in_array($filetype, $allowedExtensions)) { // If tmp_name is empty, then the file was bigger than the PHP limit if (!empty($file['tmp_name'])) { // Get the mime type this is an image file $mime = static::getMimeType($file['tmp_name'], true); // Did we get anything useful? if ($mime != false) { $result = $this->checkMimeType($mime, $component); // If the mime type is not allowed we don't upload it and show the mime code error to the user if ($result === false) { $app->enqueueMessage(Text::sprintf('JLIB_MEDIA_ERROR_WARNINVALID_MIMETYPE', $mime), 'error'); return false; } } // We can't detect the mime type so it looks like an invalid image else { $app->enqueueMessage(Text::_('JLIB_MEDIA_ERROR_WARNINVALID_IMG'), 'error'); return false; } } else { $app->enqueueMessage(Text::_('JLIB_MEDIA_ERROR_WARNFILETOOLARGE'), 'error'); return false; } } elseif (!\in_array($filetype, $ignored)) { // Get the mime type this is not an image file $mime = static::getMimeType($file['tmp_name'], false); // Did we get anything useful? if ($mime != false) { $result = $this->checkMimeType($mime, $component); // If the mime type is not allowed we don't upload it and show the mime code error to the user if ($result === false) { $app->enqueueMessage(Text::sprintf('JLIB_MEDIA_ERROR_WARNINVALID_MIMETYPE', $mime), 'error'); return false; } } // We can't detect the mime type so it looks like an invalid file else { $app->enqueueMessage(Text::_('JLIB_MEDIA_ERROR_WARNINVALID_MIME'), 'error'); return false; } if (!Factory::getUser()->authorise('core.manage', $component)) { $app->enqueueMessage(Text::_('JLIB_MEDIA_ERROR_WARNNOTADMIN'), 'error'); return false; } } } $xss_check = file_get_contents($file['tmp_name'], false, null, -1, 256); $html_tags = array( 'abbr', 'acronym', 'address', 'applet', 'area', 'audioscope', 'base', 'basefont', 'bdo', 'bgsound', 'big', 'blackface', 'blink', 'blockquote', 'body', 'bq', 'br', 'button', 'caption', 'center', 'cite', 'code', 'col', 'colgroup', 'comment', 'custom', 'dd', 'del', 'dfn', 'dir', 'div', 'dl', 'dt', 'em', 'embed', 'fieldset', 'fn', 'font', 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'hr', 'html', 'iframe', 'ilayer', 'img', 'input', 'ins', 'isindex', 'keygen', 'kbd', 'label', 'layer', 'legend', 'li', 'limittext', 'link', 'listing', 'map', 'marquee', 'menu', 'meta', 'multicol', 'nobr', 'noembed', 'noframes', 'noscript', 'nosmartquotes', 'object', 'ol', 'optgroup', 'option', 'param', 'plaintext', 'pre', 'rt', 'ruby', 's', 'samp', 'script', 'select', 'server', 'shadow', 'sidebar', 'small', 'spacer', 'span', 'strike', 'strong', 'style', 'sub', 'sup', 'table', 'tbody', 'td', 'textarea', 'tfoot', 'th', 'thead', 'title', 'tr', 'tt', 'ul', 'var', 'wbr', 'xml', 'xmp', '!DOCTYPE', '!--', ); foreach ($html_tags as $tag) { // A tag is '<tagname ', so we need to add < and a space or '<tagname>' if (stripos($xss_check, '<' . $tag . ' ') !== false || stripos($xss_check, '<' . $tag . '>') !== false) { $app->enqueueMessage(Text::_('JLIB_MEDIA_ERROR_WARNIEXSS'), 'error'); return false; } } return true; } /** * Calculate the size of a resized image * * @param integer $width Image width * @param integer $height Image height * @param integer $target Target size * * @return array The new width and height * * @since 3.2 */ public static function imageResize($width, $height, $target) { /* * Takes the larger size of the width and height and applies the * formula accordingly. This is so this script will work * dynamically with any size image */ if ($width > $height) { $percentage = ($target / $width); } else { $percentage = ($target / $height); } // Gets the new value and applies the percentage, then rounds the value $width = round($width * $percentage); $height = round($height * $percentage); return array($width, $height); } /** * Counts the files and directories in a directory that are not php or html files. * * @param string $dir Directory name * * @return array The number of media files and directories in the given directory * * @since 3.2 */ public function countFiles($dir) { $total_file = 0; $total_dir = 0; if (is_dir($dir)) { $d = dir($dir); while (($entry = $d->read()) !== false) { if ($entry[0] !== '.' && strpos($entry, '.html') === false && strpos($entry, '.php') === false && is_file($dir . DIRECTORY_SEPARATOR . $entry)) { $total_file++; } if ($entry[0] !== '.' && is_dir($dir . DIRECTORY_SEPARATOR . $entry)) { $total_dir++; } } $d->close(); } return array($total_file, $total_dir); } /** * Small helper function that properly converts any * configuration options to their byte representation. * * @param string|integer $val The value to be converted to bytes. * * @return integer The calculated bytes value from the input. * * @since 3.3 */ public function toBytes($val) { switch ($val[\strlen($val) - 1]) { case 'M': case 'm': return (int) $val * 1048576; case 'K': case 'k': return (int) $val * 1024; case 'G': case 'g': return (int) $val * 1073741824; default: return $val; } } /** * Method to check if the given directory is a directory configured in FileSystem - Local plugin * * @param string $directory * * @return boolean * * @since 4.0.0 */ public static function isValidLocalDirectory($directory) { $plugin = PluginHelper::getPlugin('filesystem', 'local'); if ($plugin) { $params = new Registry($plugin->params); $directories = $params->get('directories', '[{"directory": "images"}]'); // Do a check if default settings are not saved by user // If not initialize them manually if (is_string($directories)) { $directories = json_decode($directories); } foreach ($directories as $directoryEntity) { if ($directoryEntity->directory === $directory) { return true; } } } return false; } /** * Helper method get clean data for value stores in a Media form field by removing adapter information * from the value if available (in this case, the value will have this format: * images/headers/blue-flower.jpg#joomlaImage://local-images/headers/blue-flower.jpg?width=700&height=180) * * @param string $value * * @return string * * @since 4.0.0 */ public static function getCleanMediaFieldValue($value) { if ($pos = strpos($value, '#')) { return substr($value, 0, $pos); } return $value; } } UserGroupsHelper.php 0000604 00000013473 15252027330 0010536 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Helper; \defined('JPATH_PLATFORM') or die; use Joomla\CMS\Factory; use Joomla\Database\ParameterType; /** * Helper to deal with user groups. * * @since 3.6.3 */ final class UserGroupsHelper { /** * Indicates the current helper instance is the singleton instance. * * @var integer * @since 3.6.3 */ const MODE_SINGLETON = 1; /** * Indicates the current helper instance is a standalone class instance. * * @var integer * @since 3.6.3 */ const MODE_INSTANCE = 2; /** * Singleton instance. * * @var array * @since 3.6.3 */ private static $instance; /** * Available user groups * * @var array * @since 3.6.3 */ private $groups = array(); /** * Mode this class is working: singleton or std instance * * @var integer * @since 3.6.3 */ private $mode; /** * Total available groups * * @var integer * @since 3.6.3 */ private $total; /** * Constructor * * @param array $groups Array of groups * @param integer $mode Working mode for this class * * @since 3.6.3 */ public function __construct(array $groups = array(), $mode = self::MODE_INSTANCE) { $this->mode = (int) $mode; if ($groups) { $this->setGroups($groups); } } /** * Count loaded user groups. * * @return integer * * @since 3.6.3 */ public function count() { return \count($this->groups); } /** * Get the helper instance. * * @return self * * @since 3.6.3 */ public static function getInstance() { if (static::$instance === null) { // Only here to avoid code style issues... $groups = array(); static::$instance = new static($groups, static::MODE_SINGLETON); } return static::$instance; } /** * Get a user group by its id. * * @param integer $id Group identifier * * @return mixed stdClass on success. False otherwise * * @since 3.6.3 */ public function get($id) { if ($this->has($id)) { return $this->groups[$id]; } // Singleton will load groups as they are requested if ($this->isSingleton()) { $this->groups[$id] = $this->load($id); return $this->groups[$id]; } return false; } /** * Get the list of existing user groups. * * @return array * * @since 3.6.3 */ public function getAll() { if ($this->isSingleton() && $this->total() !== $this->count()) { $this->loadAll(); } return $this->groups; } /** * Check if a group is in the list. * * @param integer $id Group identifier * * @return boolean * * @since 3.6.3 */ public function has($id) { return (\array_key_exists($id, $this->groups) && $this->groups[$id] !== false); } /** * Check if this instance is a singleton. * * @return boolean * * @since 3.6.3 */ private function isSingleton() { return $this->mode === static::MODE_SINGLETON; } /** * Get total available user groups in database. * * @return integer * * @since 3.6.3 */ public function total() { if ($this->total === null) { $db = Factory::getDbo(); $query = $db->getQuery(true) ->select('COUNT(' . $db->quoteName('id') . ')') ->from($db->quoteName('#__usergroups')); $db->setQuery($query); $this->total = (int) $db->loadResult(); } return $this->total; } /** * Load a group from database. * * @param integer $id Group identifier * * @return mixed * * @since 3.6.3 */ public function load($id) { // Cast as integer until method is typehinted. $id = (int) $id; $db = Factory::getDbo(); $query = $db->getQuery(true) ->select('*') ->from($db->quoteName('#__usergroups')) ->where($db->quoteName('id') . ' = :id') ->bind(':id', $id, ParameterType::INTEGER); $db->setQuery($query); $group = $db->loadObject(); if (!$group) { return false; } return $this->populateGroupData($group); } /** * Load all user groups from the database. * * @return self * * @since 3.6.3 */ public function loadAll() { $this->groups = array(); $db = Factory::getDbo(); $query = $db->getQuery(true) ->select('*') ->from($db->quoteName('#__usergroups')) ->order($db->quoteName('lft') . ' ASC'); $db->setQuery($query); $groups = $db->loadObjectList('id'); $this->groups = $groups ?: array(); $this->populateGroupsData(); return $this; } /** * Populates extra information for groups. * * @return array * * @since 3.6.3 */ private function populateGroupsData() { foreach ($this->groups as $group) { $this->populateGroupData($group); } return $this->groups; } /** * Populate data for a specific user group. * * @param \stdClass $group Group * * @return \stdClass * * @since 3.6.3 */ public function populateGroupData($group) { if (!$group || property_exists($group, 'path')) { return $group; } $parentId = (int) $group->parent_id; if ($parentId === 0) { $group->path = array($group->id); $group->level = 0; return $group; } $parentGroup = $this->has($parentId) ? $this->get($parentId) : $this->load($parentId); if (!property_exists($parentGroup, 'path')) { $parentGroup = $this->populateGroupData($parentGroup); } $group->path = array_merge($parentGroup->path, array($group->id)); $group->level = \count($group->path) - 1; return $group; } /** * Set the groups to be used as source. * * @param array $groups Array of user groups. * * @return self * * @since 3.6.3 */ public function setGroups(array $groups) { $this->groups = $groups; $this->populateGroupsData(); $this->total = \count($groups); return $this; } } .mad-root 0000644 00000000000 15252027330 0006254 0 ustar 00 ContentHelper.php 0000604 00000016117 15252027330 0010030 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Helper; \defined('JPATH_PLATFORM') or die; use Joomla\CMS\Access\Access; use Joomla\CMS\Application\ApplicationHelper; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Factory; use Joomla\CMS\Language\LanguageHelper; use Joomla\CMS\Language\Multilanguage; use Joomla\CMS\Language\Text; use Joomla\CMS\Log\Log; use Joomla\CMS\Object\CMSObject; use Joomla\CMS\Plugin\PluginHelper; use Joomla\CMS\Table\Table; use Joomla\Registry\Registry; /** * Helper for standard content style extensions. * This class mainly simplifies static helper methods often repeated in individual components * * @since 3.1 */ class ContentHelper { /** * Configure the Linkbar. Must be implemented by each extension. * * @param string $vName The name of the active view. * * @return void * * @since 3.1 */ public static function addSubmenu($vName) { } /** * Adds Count relations for Category and Tag Managers * * @param \stdClass[] &$items The category or tag objects * @param \stdClass $config Configuration object allowing to use a custom relations table * * @return \stdClass[] * * @since 3.9.1 */ public static function countRelations(&$items, $config) { $db = Factory::getDbo(); // Allow custom state / condition values and custom column names to support custom components $counter_names = isset($config->counter_names) ? $config->counter_names : array( '-2' => 'count_trashed', '0' => 'count_unpublished', '1' => 'count_published', '2' => 'count_archived', ); // Index category objects by their ID $records = array(); foreach ($items as $item) { $records[(int) $item->id] = $item; } // The relation query does not return a value for cases without relations of a particular state / condition, set zero as default foreach ($items as $item) { foreach ($counter_names as $n) { $item->{$n} = 0; } } // Table alias for related data table below will be 'c', and state / condition column is inside related data table $related_tbl = '#__' . $config->related_tbl; $state_col = 'c.' . $config->state_col; // Supported cases switch ($config->relation_type) { case 'tag_assigments': $recid_col = 'ct.' . $config->group_col; $query = $db->getQuery(true) ->from($db->quoteName('#__contentitem_tag_map', 'ct')) ->join( 'INNER', $db->quoteName($related_tbl, 'c'), $db->quoteName('ct.content_item_id') . ' = ' . $db->quoteName('c.id') . ' AND ' . $db->quoteName('ct.type_alias') . ' = :extension' ) ->bind(':extension', $config->extension); break; case 'category_or_group': $recid_col = 'c.' . $config->group_col; $query = $db->getQuery(true) ->from($db->quoteName($related_tbl, 'c')); break; default: return $items; } /** * Get relation counts for all category objects with single query * NOTE: 'state IN', allows counting specific states / conditions only, also prevents warnings with custom states / conditions, do not remove */ $query ->select( [ $db->quoteName($recid_col, 'catid'), $db->quoteName($state_col, 'state'), 'COUNT(*) AS ' . $db->quoteName('count'), ] ) ->whereIn($db->quoteName($recid_col), array_keys($records)) ->whereIn($db->quoteName($state_col), array_keys($counter_names)) ->group($db->quoteName([$recid_col, $state_col])); $relationsAll = $db->setQuery($query)->loadObjectList(); // Loop through the DB data overwriting the above zeros with the found count foreach ($relationsAll as $relation) { // Sanity check in case someone removes the state IN above ... and some views may start throwing warnings if (isset($counter_names[$relation->state])) { $id = (int) $relation->catid; $cn = $counter_names[$relation->state]; $records[$id]->{$cn} = $relation->count; } } return $items; } /** * Gets a list of the actions that can be performed. * * @param string $component The component name. * @param string $section The access section name. * @param integer $id The item ID. * * @return CMSObject * * @since 3.2 */ public static function getActions($component = '', $section = '', $id = 0) { $assetName = $component; if ($section && $id) { $assetName .= '.' . $section . '.' . (int) $id; } $result = new CMSObject; $user = Factory::getUser(); $actions = Access::getActionsFromFile( JPATH_ADMINISTRATOR . '/components/' . $component . '/access.xml', '/access/section[@name="component"]/' ); if ($actions === false) { Log::add( Text::sprintf('JLIB_ERROR_COMPONENTS_ACL_CONFIGURATION_FILE_MISSING_OR_IMPROPERLY_STRUCTURED', $component), Log::ERROR, 'jerror' ); return $result; } foreach ($actions as $action) { $result->set($action->name, $user->authorise($action->name, $assetName)); } return $result; } /** * Gets the current language * * @param boolean $detectBrowser Flag indicating whether to use the browser language as a fallback. * * @return string The language string * * @since 3.1 * @note CmsHelper::getCurrentLanguage is the preferred method */ public static function getCurrentLanguage($detectBrowser = true) { $app = Factory::getApplication(); $langCode = null; // Get the languagefilter parameters if (Multilanguage::isEnabled()) { $plugin = PluginHelper::getPlugin('system', 'languagefilter'); $pluginParams = new Registry($plugin->params); if ((int) $pluginParams->get('lang_cookie', 1) === 1) { $langCode = $app->input->cookie->getString(ApplicationHelper::getHash('language')); } else { $langCode = $app->getSession()->get('plg_system_languagefilter.language'); } } // No cookie - let's try to detect browser language or use site default if (!$langCode) { if ($detectBrowser) { $langCode = LanguageHelper::detectLanguage(); } else { $langCode = ComponentHelper::getParams('com_languages')->get('site', 'en-GB'); } } return $langCode; } /** * Gets the associated language ID * * @param string $langCode The language code to look up * * @return integer The language ID * * @since 3.1 * @note CmsHelper::getLanguage() is the preferred method. */ public static function getLanguageId($langCode) { $db = Factory::getDbo(); $query = $db->getQuery(true) ->select($db->quoteName('lang_id')) ->from($db->quoteName('#__languages')) ->where($db->quoteName('lang_code') . ' = :language') ->bind(':language', $langCode); $db->setQuery($query); return $db->loadResult(); } /** * Gets a row of data from a table * * @param Table $table Table instance for a row. * * @return array Associative array of all columns and values for a row in a table. * * @since 3.1 */ public function getRowData(Table $table) { $data = new CMSHelper; return $data->getRowData($table); } } RouteHelper.php 0000604 00000007222 15252027330 0007511 0 ustar 00 <?php /** * @package Joomla.Site * @subpackage com_finder * * @copyright (C) 2020 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Component\Finder\Site\Helper; \defined('_JEXEC') or die; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Factory; use Joomla\CMS\Uri\Uri; /** * Finder route helper class. * * @since 2.5 */ class RouteHelper { /** * Method to get the route for a search page. * * @param integer $f The search filter id. [optional] * @param string $q The search query string. [optional] * * @return string The search route. * * @since 2.5 */ public static function getSearchRoute($f = null, $q = null) { // Get the menu item id. $query = array('view' => 'search', 'q' => $q, 'f' => $f); $item = self::getItemid($query); // Get the base route. $uri = clone Uri::getInstance('index.php?option=com_finder&view=search'); // Add the pre-defined search filter if present. if ($f !== null) { $uri->setVar('f', $f); } // Add the search query string if present. if ($q !== null) { $uri->setVar('q', $q); } // Add the menu item id if present. if ($item !== null) { $uri->setVar('Itemid', $item); } return $uri->toString(array('path', 'query')); } /** * Method to get the route for an advanced search page. * * @param integer $f The search filter id. [optional] * @param string $q The search query string. [optional] * * @return string The advanced search route. * * @since 2.5 */ public static function getAdvancedRoute($f = null, $q = null) { // Get the menu item id. $query = array('view' => 'advanced', 'q' => $q, 'f' => $f); $item = self::getItemid($query); // Get the base route. $uri = clone Uri::getInstance('index.php?option=com_finder&view=advanced'); // Add the pre-defined search filter if present. if ($q !== null) { $uri->setVar('f', $f); } // Add the search query string if present. if ($q !== null) { $uri->setVar('q', $q); } // Add the menu item id if present. if ($item !== null) { $uri->setVar('Itemid', $item); } return $uri->toString(array('path', 'query')); } /** * Method to get the most appropriate menu item for the route based on the * supplied query needles. * * @param array $query An array of URL parameters. * * @return mixed An integer on success, null otherwise. * * @since 2.5 */ public static function getItemid($query) { static $items, $active; // Get the menu items for com_finder. if (!$items || !$active) { $app = Factory::getApplication(); $com = ComponentHelper::getComponent('com_finder'); $menu = $app->getMenu(); $active = $menu->getActive(); $items = $menu->getItems('component_id', $com->id); $items = is_array($items) ? $items : array(); } // Try to match the active view and filter. if ($active && @$active->query['view'] == @$query['view'] && @$active->query['f'] == @$query['f']) { return $active->id; } // Try to match the view, query, and filter. foreach ($items as $item) { if (@$item->query['view'] == @$query['view'] && @$item->query['q'] == @$query['q'] && @$item->query['f'] == @$query['f']) { return $item->id; } } // Try to match the view and filter. foreach ($items as $item) { if (@$item->query['view'] == @$query['view'] && @$item->query['f'] == @$query['f']) { return $item->id; } } // Try to match the view. foreach ($items as $item) { if (@$item->query['view'] == @$query['view']) { return $item->id; } } return null; } } HelperFactory.php 0000604 00000002164 15252027330 0010022 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2021 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE */ namespace Joomla\CMS\Helper; \defined('_JEXEC') or die; /** * Namespace based implementation of the HelperFactoryInterface * * @since 4.0.0 */ class HelperFactory implements HelperFactoryInterface { /** * The extension namespace * * @var string * * @since 4.0.0 */ private $namespace; /** * HelperFactory constructor. * * @param string $namespace The namespace * * @since 4.0.0 */ public function __construct(string $namespace) { $this->namespace = $namespace; } /** * Returns a helper instance for the given name. * * @param string $name The name * @param array $config The config * * @return \stdClass * * @since 4.0.0 */ public function getHelper(string $name, array $config = []) { $className = '\\' . trim($this->namespace, '\\') . '\\' . $name; if (!class_exists($className)) { return null; } return new $className($config); } } AuthenticationHelper.php 0000604 00000012753 15252027330 0011377 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Helper; \defined('JPATH_PLATFORM') or die; use Exception; use Joomla\CMS\Application\CMSApplication; use Joomla\CMS\Factory; use Joomla\CMS\HTML\HTMLHelper; use Joomla\CMS\Language\Text; use Joomla\CMS\Plugin\PluginHelper; /** * Authentication helper class * * @since 3.6.3 */ abstract class AuthenticationHelper { /** * Get the Two Factor Authentication Methods available. * * @return array Two factor authentication methods. * * @since 3.6.3 */ public static function getTwoFactorMethods() { // Get all the Two Factor Authentication plugins. PluginHelper::importPlugin('twofactorauth'); // Trigger onUserTwofactorIdentify event and return the two factor enabled plugins. $identities = Factory::getApplication()->triggerEvent('onUserTwofactorIdentify', array()); // Generate array with two factor auth methods. $options = array( HTMLHelper::_('select.option', 'none', Text::_('JGLOBAL_OTPMETHOD_NONE'), 'value', 'text'), ); if (!empty($identities)) { foreach ($identities as $identity) { if (!\is_object($identity)) { continue; } $options[] = HTMLHelper::_('select.option', $identity->method, $identity->title, 'value', 'text'); } } return $options; } /** * Get additional login buttons to add in a login module. These buttons can be used for * authentication methods external to Joomla such as WebAuthn, login with social media * providers, login with third party providers or even login with third party Single Sign On * (SSO) services. * * Button definitions are returned by the onUserLoginButtons event handlers in plugins. By * default, only system and user plugins are taken into account. The former because they are * always loaded. The latter are explicitly loaded in this method. * * The onUserLoginButtons event handlers must conform to the following method definition: * * public function onUserLoginButtons(string $formId): array * * The onUserLoginButtons event handlers must return a simple array containing 0 or more button * definitions. * * Each button definition is a hash array with the following keys: * * * `label` The translation string used as the label and title of the button. Required * * `id` The HTML ID of the button. Required. * * `tooltip` (optional) The translation string used as the alt tag of the button's image * * `onclick` (optional) The onclick attribute, used to fire a JavaScript event. Not * recommended. * * `data-*` (optional) Data attributes to pass verbatim. Use these and JavaScript to handle * the button. * * `icon` (optional) A CSS class for an optional icon displayed before the label; has * precedence over 'image' * * `image` (optional) An image path for an optional icon displayed before the label * * `class` (optional) CSS class(es) to be added to the button * * You can find a real world implementation of the onUserLoginButtons plugin event in the * system/webauthn plugin. * * You can find a real world implementation of consuming the output of this method in the * modules/mod_login module. * * Third party developers implementing a login module or a login form in their component are * strongly advised to call this method and consume its results to display additional login * buttons. Not doing that means that you are not fully compatible with Joomla 4. * * @param string $formId The HTML ID of the login form container. Use it to filter when and * where to show your additional login button(s) * * @return array Button definitions. * * @since 4.0.0 */ public static function getLoginButtons(string $formId): array { // Get all the User plugins. PluginHelper::importPlugin('user'); // Trigger the onUserLoginButtons event and return the button definitions. try { /** @var CMSApplication $app */ $app = Factory::getApplication(); } catch (Exception $e) { return []; } $results = $app->triggerEvent('onUserLoginButtons', [$formId]); $buttons = []; foreach ($results as $result) { // Did we get garbage back from the plugin? if (!is_array($result) || empty($result)) { continue; } // Did the developer accidentally return a single button definition instead of an array? if (array_key_exists('label', $result)) { $result = [$result]; } // Process each button, making sure it conforms to the required definition foreach ($result as $item) { // Force mandatory fields $defaultButtonDefinition = [ 'label' => '', 'tooltip' => '', 'icon' => '', 'image' => '', 'class' => '', 'id' => '', 'onclick' => '', ]; $button = array_merge($defaultButtonDefinition, $item); // Unset anything that doesn't conform to a button definition foreach (array_keys($button) as $key) { if (substr($key, 0, 5) == 'data-') { continue; } if (!in_array($key, ['label', 'tooltip', 'icon', 'image', 'svg', 'class', 'id', 'onclick'])) { unset($button[$key]); } } // We need a label and an ID as the bare minimum if (empty($button['label']) || empty($button['id'])) { continue; } $buttons[] = $button; } } return $buttons; } } HelperFactoryInterface.php 0000604 00000001166 15252027330 0011644 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2021 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Helper; \defined('JPATH_PLATFORM') or die; /** * Factory to load helper classes. * * @since 4.0.0 */ interface HelperFactoryInterface { /** * Returns a helper instance for the given name. * * @param string $name The name * @param array $config The config * * @return \stdClass * * @since 4.0.0 */ public function getHelper(string $name, array $config = []); } CMSHelper.php 0000604 00000006245 15252027330 0007041 0 ustar 00 <?php /** * Joomla! Content Management System * * @copyright (C) 2013 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\CMS\Helper; \defined('JPATH_PLATFORM') or die; use Joomla\CMS\Application\ApplicationHelper; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Factory; use Joomla\CMS\Language\LanguageHelper; use Joomla\CMS\Language\Multilanguage; use Joomla\CMS\Plugin\PluginHelper; use Joomla\CMS\Table\TableInterface; use Joomla\Registry\Registry; /** * Base Helper class. * * @since 3.2 */ class CMSHelper { /** * Gets the current language * * @param boolean $detectBrowser Flag indicating whether to use the browser language as a fallback. * * @return string The language string * * @since 3.2 */ public function getCurrentLanguage($detectBrowser = true) { $app = Factory::getApplication(); $langCode = null; // Get the languagefilter parameters if (Multilanguage::isEnabled()) { $plugin = PluginHelper::getPlugin('system', 'languagefilter'); $pluginParams = new Registry($plugin->params); if ((int) $pluginParams->get('lang_cookie', 1) === 1) { $langCode = $app->input->cookie->getString(ApplicationHelper::getHash('language')); } else { $langCode = $app->getSession()->get('plg_system_languagefilter.language'); } } // No cookie - let's try to detect browser language or use site default if (!$langCode) { if ($detectBrowser) { $langCode = LanguageHelper::detectLanguage(); } else { $langCode = ComponentHelper::getParams('com_languages')->get('site', 'en-GB'); } } return $langCode; } /** * Gets the associated language ID * * @param string $langCode The language code to look up * * @return integer The language ID * * @since 3.2 */ public function getLanguageId($langCode) { $db = Factory::getDbo(); $query = $db->getQuery(true) ->select($db->quoteName('lang_id')) ->from($db->quoteName('#__languages')) ->where($db->quoteName('lang_code') . ' = :language') ->bind(':language', $langCode); $db->setQuery($query); return $db->loadResult(); } /** * Gets a row of data from a table * * @param TableInterface $table Table instance for a row. * * @return array Associative array of all columns and values for a row in a table. * * @since 3.2 */ public function getRowData(TableInterface $table) { $fields = $table->getFields(); $data = array(); foreach ($fields as &$field) { $columnName = $field->Field; $value = $table->$columnName; $data[$columnName] = $value; } return $data; } /** * Method to get an object containing all of the table columns and values. * * @param TableInterface $table Table object. * * @return \stdClass Contains all of the columns and values. * * @since 3.2 */ public function getDataObject(TableInterface $table) { $fields = $table->getFields(); $dataObject = new \stdClass; foreach ($fields as $field) { $fieldName = $field->Field; $dataObject->$fieldName = $table->get($fieldName); } return $dataObject; } } FinderHelper.php 0000604 00000005171 15252034105 0007621 0 ustar 00 <?php /** * @package Joomla.Site * @subpackage com_finder * * @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org> * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace Joomla\Component\Finder\Site\Helper; \defined('JPATH_PLATFORM') or die; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Factory; use Joomla\Component\Finder\Administrator\Indexer\Query; use Joomla\Database\ParameterType; /** * Helper class for Joomla! Finder components * * @since 4.0.0 */ class FinderHelper { /** * Method to log searches to the database * * @param Query $searchquery The search query * @param integer $resultCount The number of results for this search * * @return void * * @since 4.0.0 */ public static function logSearch(Query $searchquery, $resultCount = 0) { if (!ComponentHelper::getParams('com_finder')->get('gather_search_statistics', 0)) { return; } if (trim($searchquery->input) == '' && !$searchquery->empty) { return; } // Initialise our variables $db = Factory::getDbo(); $query = $db->getQuery(true); // Sanitise the term for the database $temp = unserialize(serialize($searchquery)); $temp->input = trim(strtolower($searchquery->input)); $entry = new \stdClass; $entry->searchterm = $temp->input; $entry->query = serialize($temp); $entry->md5sum = md5($entry->query); $entry->hits = 1; $entry->results = $resultCount; // Query the table to determine if the term has been searched previously $query->select($db->quoteName('hits')) ->from($db->quoteName('#__finder_logging')) ->where($db->quoteName('md5sum') . ' = ' . $db->quote($entry->md5sum)); $db->setQuery($query); $hits = (int) $db->loadResult(); // Reset the $query object $query->clear(); // Update the table based on the results if ($hits) { $query->update($db->quoteName('#__finder_logging')) ->set('hits = (hits + 1)') ->where($db->quoteName('md5sum') . ' = ' . $db->quote($entry->md5sum)); $db->setQuery($query); $db->execute(); } else { $query->insert($db->quoteName('#__finder_logging')) ->columns( [ $db->quoteName('searchterm'), $db->quoteName('query'), $db->quoteName('md5sum'), $db->quoteName('hits'), $db->quoteName('results'), ] ) ->values('?, ?, ?, ?, ?') ->bind(1, $entry->searchterm) ->bind(2, $entry->query, ParameterType::LARGE_OBJECT) ->bind(3, $entry->md5sum) ->bind(4, $entry->hits, ParameterType::INTEGER) ->bind(5, $entry->results, ParameterType::INTEGER); $db->setQuery($query); $db->execute(); } } }
| ver. 1.4 |
Github
|
.
| PHP 8.5.7 | Generation time: 0 |
proxy
|
phpinfo
|
Settings