[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * @package Joomla.Administrator 5 * @subpackage com_actionlogs 6 * 7 * @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org> 8 * @license GNU General Public License version 2 or later; see LICENSE.txt 9 */ 10 11 namespace Joomla\Component\Actionlogs\Administrator\Helper; 12 13 use Generator; 14 use Joomla\CMS\Date\Date; 15 use Joomla\CMS\Factory; 16 use Joomla\CMS\Filesystem\Path; 17 use Joomla\CMS\Language\Text; 18 use Joomla\CMS\Object\CMSObject; 19 use Joomla\CMS\Router\Route; 20 use Joomla\String\StringHelper; 21 22 // phpcs:disable PSR1.Files.SideEffects 23 \defined('_JEXEC') or die; 24 // phpcs:enable PSR1.Files.SideEffects 25 26 /** 27 * Actionlogs component helper. 28 * 29 * @since 3.9.0 30 */ 31 class ActionlogsHelper 32 { 33 /** 34 * Array of characters starting a formula 35 * 36 * @var array 37 * 38 * @since 3.9.7 39 */ 40 private static $characters = array('=', '+', '-', '@'); 41 42 /** 43 * Method to convert logs objects array to an iterable type for use with a CSV export 44 * 45 * @param array|\Traversable $data The logs data objects to be exported 46 * 47 * @return Generator 48 * 49 * @since 3.9.0 50 * 51 * @throws \InvalidArgumentException 52 */ 53 public static function getCsvData($data): Generator 54 { 55 if (!is_iterable($data)) { 56 throw new \InvalidArgumentException( 57 sprintf( 58 '%s() requires an array or object implementing the Traversable interface, a %s was given.', 59 __METHOD__, 60 \gettype($data) === 'object' ? \get_class($data) : \gettype($data) 61 ) 62 ); 63 } 64 65 $disabledText = Text::_('COM_ACTIONLOGS_DISABLED'); 66 67 // Header row 68 yield ['Id', 'Action', 'Extension', 'Date', 'Name', 'IP Address']; 69 70 foreach ($data as $log) { 71 $extension = strtok($log->extension, '.'); 72 73 static::loadTranslationFiles($extension); 74 75 yield array( 76 'id' => $log->id, 77 'message' => self::escapeCsvFormula(strip_tags(static::getHumanReadableLogMessage($log, false))), 78 'extension' => self::escapeCsvFormula(Text::_($extension)), 79 'date' => (new Date($log->log_date, new \DateTimeZone('UTC')))->format('Y-m-d H:i:s T'), 80 'name' => self::escapeCsvFormula($log->name), 81 'ip_address' => self::escapeCsvFormula($log->ip_address === 'COM_ACTIONLOGS_DISABLED' ? $disabledText : $log->ip_address) 82 ); 83 } 84 } 85 86 /** 87 * Load the translation files for an extension 88 * 89 * @param string $extension Extension name 90 * 91 * @return void 92 * 93 * @since 3.9.0 94 */ 95 public static function loadTranslationFiles($extension) 96 { 97 static $cache = array(); 98 $extension = strtolower($extension); 99 100 if (isset($cache[$extension])) { 101 return; 102 } 103 104 $lang = Factory::getLanguage(); 105 $source = ''; 106 107 switch (substr($extension, 0, 3)) { 108 case 'com': 109 default: 110 $source = JPATH_ADMINISTRATOR . '/components/' . $extension; 111 break; 112 113 case 'lib': 114 $source = JPATH_LIBRARIES . '/' . substr($extension, 4); 115 break; 116 117 case 'mod': 118 $source = JPATH_SITE . '/modules/' . $extension; 119 break; 120 121 case 'plg': 122 $parts = explode('_', $extension, 3); 123 124 if (\count($parts) > 2) { 125 $source = JPATH_PLUGINS . '/' . $parts[1] . '/' . $parts[2]; 126 } 127 break; 128 129 case 'pkg': 130 $source = JPATH_SITE; 131 break; 132 133 case 'tpl': 134 $source = JPATH_BASE . '/templates/' . substr($extension, 4); 135 break; 136 } 137 138 $lang->load($extension, JPATH_ADMINISTRATOR) 139 || $lang->load($extension, $source); 140 141 if (!$lang->hasKey(strtoupper($extension))) { 142 $lang->load($extension . '.sys', JPATH_ADMINISTRATOR) 143 || $lang->load($extension . '.sys', $source); 144 } 145 146 $cache[$extension] = true; 147 } 148 149 /** 150 * Get parameters to be 151 * 152 * @param string $context The context of the content 153 * 154 * @return mixed An object contains content type parameters, or null if not found 155 * 156 * @since 3.9.0 157 * 158 * @deprecated 5.0 Use the action log config model instead 159 */ 160 public static function getLogContentTypeParams($context) 161 { 162 return Factory::getApplication()->bootComponent('actionlogs')->getMVCFactory() 163 ->createModel('ActionlogConfig', 'Administrator')->getLogContentTypeParams($context); 164 } 165 166 /** 167 * Get human readable log message for a User Action Log 168 * 169 * @param \stdClass $log A User Action log message record 170 * @param boolean $generateLinks Flag to disable link generation when creating a message 171 * 172 * @return string 173 * 174 * @since 3.9.0 175 */ 176 public static function getHumanReadableLogMessage($log, $generateLinks = true) 177 { 178 static $links = array(); 179 180 $message = Text::_($log->message_language_key); 181 $messageData = json_decode($log->message, true); 182 183 // Special handling for translation extension name 184 if (isset($messageData['extension_name'])) { 185 static::loadTranslationFiles($messageData['extension_name']); 186 $messageData['extension_name'] = Text::_($messageData['extension_name']); 187 } 188 189 // Translating application 190 if (isset($messageData['app'])) { 191 $messageData['app'] = Text::_($messageData['app']); 192 } 193 194 // Translating type 195 if (isset($messageData['type'])) { 196 $messageData['type'] = Text::_($messageData['type']); 197 } 198 199 $linkMode = Factory::getApplication()->get('force_ssl', 0) >= 1 ? Route::TLS_FORCE : Route::TLS_IGNORE; 200 201 foreach ($messageData as $key => $value) { 202 // Escape any markup in the values to prevent XSS attacks 203 $value = htmlspecialchars($value, ENT_QUOTES, 'UTF-8'); 204 205 // Convert relative url to absolute url so that it is clickable in action logs notification email 206 if ($generateLinks && StringHelper::strpos($value, 'index.php?') === 0) { 207 if (!isset($links[$value])) { 208 $links[$value] = Route::link('administrator', $value, false, $linkMode, true); 209 } 210 211 $value = $links[$value]; 212 } 213 214 $message = str_replace('{' . $key . '}', $value, $message); 215 } 216 217 return $message; 218 } 219 220 /** 221 * Get link to an item of given content type 222 * 223 * @param string $component 224 * @param string $contentType 225 * @param integer $id 226 * @param string $urlVar 227 * @param CMSObject $object 228 * 229 * @return string Link to the content item 230 * 231 * @since 3.9.0 232 */ 233 public static function getContentTypeLink($component, $contentType, $id, $urlVar = 'id', $object = null) 234 { 235 // Try to find the component helper. 236 $eName = str_replace('com_', '', $component); 237 $file = Path::clean(JPATH_ADMINISTRATOR . '/components/' . $component . '/helpers/' . $eName . '.php'); 238 239 if (file_exists($file)) { 240 $prefix = ucfirst(str_replace('com_', '', $component)); 241 $cName = $prefix . 'Helper'; 242 243 \JLoader::register($cName, $file); 244 245 if (class_exists($cName) && \is_callable(array($cName, 'getContentTypeLink'))) { 246 return $cName::getContentTypeLink($contentType, $id, $object); 247 } 248 } 249 250 if (empty($urlVar)) { 251 $urlVar = 'id'; 252 } 253 254 // Return default link to avoid having to implement getContentTypeLink in most of our components 255 return 'index.php?option=' . $component . '&task=' . $contentType . '.edit&' . $urlVar . '=' . $id; 256 } 257 258 /** 259 * Load both enabled and disabled actionlog plugins language file. 260 * 261 * It is used to make sure actions log is displayed properly instead of only language items displayed when a plugin is disabled. 262 * 263 * @return void 264 * 265 * @since 3.9.0 266 */ 267 public static function loadActionLogPluginsLanguage() 268 { 269 $lang = Factory::getLanguage(); 270 $db = Factory::getDbo(); 271 272 // Get all (both enabled and disabled) actionlog plugins 273 $query = $db->getQuery(true) 274 ->select( 275 $db->quoteName( 276 array( 277 'folder', 278 'element', 279 'params', 280 'extension_id' 281 ), 282 array( 283 'type', 284 'name', 285 'params', 286 'id' 287 ) 288 ) 289 ) 290 ->from('#__extensions') 291 ->where('type = ' . $db->quote('plugin')) 292 ->where('folder = ' . $db->quote('actionlog')) 293 ->where('state IN (0,1)') 294 ->order('ordering'); 295 $db->setQuery($query); 296 297 try { 298 $rows = $db->loadObjectList(); 299 } catch (\RuntimeException $e) { 300 $rows = array(); 301 } 302 303 if (empty($rows)) { 304 return; 305 } 306 307 foreach ($rows as $row) { 308 $name = $row->name; 309 $type = $row->type; 310 $extension = 'Plg_' . $type . '_' . $name; 311 $extension = strtolower($extension); 312 313 // If language already loaded, don't load it again. 314 if ($lang->getPaths($extension)) { 315 continue; 316 } 317 318 $lang->load($extension, JPATH_ADMINISTRATOR) 319 || $lang->load($extension, JPATH_PLUGINS . '/' . $type . '/' . $name); 320 } 321 322 // Load plg_system_actionlogs too 323 $lang->load('plg_system_actionlogs', JPATH_ADMINISTRATOR); 324 325 // Load com_privacy too. 326 $lang->load('com_privacy', JPATH_ADMINISTRATOR); 327 } 328 329 /** 330 * Escapes potential characters that start a formula in a CSV value to prevent injection attacks 331 * 332 * @param mixed $value csv field value 333 * 334 * @return mixed 335 * 336 * @since 3.9.7 337 */ 338 protected static function escapeCsvFormula($value) 339 { 340 if ($value == '') { 341 return $value; 342 } 343 344 if (\in_array($value[0], self::$characters, true)) { 345 $value = ' ' . $value; 346 } 347 348 return $value; 349 } 350 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |