primo commit
This commit is contained in:
		
							
								
								
									
										620
									
								
								plugins/system/stats/src/Extension/Stats.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										620
									
								
								plugins/system/stats/src/Extension/Stats.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,620 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Plugin | ||||
|  * @subpackage  System.stats | ||||
|  * | ||||
|  * @copyright   (C) 2015 Open Source Matters, Inc. <https://www.joomla.org> | ||||
|  * @license     GNU General Public License version 2 or later; see LICENSE.txt | ||||
|  */ | ||||
|  | ||||
| namespace Joomla\Plugin\System\Stats\Extension; | ||||
|  | ||||
| use Joomla\CMS\Cache\Cache; | ||||
| use Joomla\CMS\Http\HttpFactory; | ||||
| use Joomla\CMS\Layout\FileLayout; | ||||
| use Joomla\CMS\Log\Log; | ||||
| use Joomla\CMS\Plugin\CMSPlugin; | ||||
| use Joomla\CMS\User\UserHelper; | ||||
| use Joomla\Database\DatabaseAwareTrait; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| // Uncomment the following line to enable debug mode for testing purposes. Note: statistics will be sent on every page load | ||||
| // define('PLG_SYSTEM_STATS_DEBUG', 1); | ||||
|  | ||||
| /** | ||||
|  * Statistics system plugin. This sends anonymous data back to the Joomla! Project about the | ||||
|  * PHP, SQL, Joomla and OS versions | ||||
|  * | ||||
|  * @since  3.5 | ||||
|  */ | ||||
| final class Stats extends CMSPlugin | ||||
| { | ||||
|     use DatabaseAwareTrait; | ||||
|  | ||||
|     /** | ||||
|      * Indicates sending statistics is always allowed. | ||||
|      * | ||||
|      * @var    integer | ||||
|      * | ||||
|      * @since  3.5 | ||||
|      */ | ||||
|     public const MODE_ALLOW_ALWAYS = 1; | ||||
|  | ||||
|     /** | ||||
|      * Indicates sending statistics is never allowed. | ||||
|      * | ||||
|      * @var    integer | ||||
|      * | ||||
|      * @since  3.5 | ||||
|      */ | ||||
|     public const MODE_ALLOW_NEVER = 3; | ||||
|  | ||||
|     /** | ||||
|      * URL to send the statistics. | ||||
|      * | ||||
|      * @var    string | ||||
|      * | ||||
|      * @since  3.5 | ||||
|      */ | ||||
|     protected $serverUrl = 'https://developer.joomla.org/stats/submit'; | ||||
|  | ||||
|     /** | ||||
|      * Unique identifier for this site | ||||
|      * | ||||
|      * @var    string | ||||
|      * | ||||
|      * @since  3.5 | ||||
|      */ | ||||
|     protected $uniqueId; | ||||
|  | ||||
|     /** | ||||
|      * Listener for the `onAfterInitialise` event | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   3.5 | ||||
|      */ | ||||
|     public function onAfterInitialise() | ||||
|     { | ||||
|         if (!$this->getApplication()->isClient('administrator') || !$this->isAllowedUser()) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if ($this->isCaptiveMFA()) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (!$this->isDebugEnabled() && !$this->isUpdateRequired()) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if ($this->getApplication()->getInput()->getVar('tmpl') === 'component') { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // Load plugin language files only when needed (ex: they are not needed in site client). | ||||
|         $this->loadLanguage(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Listener for the `onAfterDispatch` event | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   4.0.0 | ||||
|      */ | ||||
|     public function onAfterDispatch() | ||||
|     { | ||||
|         if (!$this->getApplication()->isClient('administrator') || !$this->isAllowedUser()) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if ($this->isCaptiveMFA()) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (!$this->isDebugEnabled() && !$this->isUpdateRequired()) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if ($this->getApplication()->getInput()->getVar('tmpl') === 'component') { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if ($this->getApplication()->getDocument()->getType() !== 'html') { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         $this->getApplication()->getDocument()->getWebAssetManager() | ||||
|             ->registerAndUseScript('plg_system_stats.message', 'plg_system_stats/stats-message.js', [], ['defer' => true], ['core']); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * User selected to always send data | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   3.5 | ||||
|      * | ||||
|      * @throws  \Exception         If user is not allowed. | ||||
|      * @throws  \RuntimeException  If there is an error saving the params or sending the data. | ||||
|      */ | ||||
|     public function onAjaxSendAlways() | ||||
|     { | ||||
|         if (!$this->isAllowedUser() || !$this->isAjaxRequest()) { | ||||
|             throw new \Exception($this->getApplication()->getLanguage()->_('JGLOBAL_AUTH_ACCESS_DENIED'), 403); | ||||
|         } | ||||
|  | ||||
|         $this->params->set('mode', static::MODE_ALLOW_ALWAYS); | ||||
|  | ||||
|         if (!$this->saveParams()) { | ||||
|             throw new \RuntimeException('Unable to save plugin settings', 500); | ||||
|         } | ||||
|  | ||||
|         echo json_encode(['sent' => (int) $this->sendStats()]); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * User selected to never send data. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   3.5 | ||||
|      * | ||||
|      * @throws  \Exception         If user is not allowed. | ||||
|      * @throws  \RuntimeException  If there is an error saving the params. | ||||
|      */ | ||||
|     public function onAjaxSendNever() | ||||
|     { | ||||
|         if (!$this->isAllowedUser() || !$this->isAjaxRequest()) { | ||||
|             throw new \Exception($this->getApplication()->getLanguage()->_('JGLOBAL_AUTH_ACCESS_DENIED'), 403); | ||||
|         } | ||||
|  | ||||
|         $this->params->set('mode', static::MODE_ALLOW_NEVER); | ||||
|  | ||||
|         if (!$this->saveParams()) { | ||||
|             throw new \RuntimeException('Unable to save plugin settings', 500); | ||||
|         } | ||||
|  | ||||
|         if (!$this->disablePlugin()) { | ||||
|             throw new \RuntimeException('Unable to disable the statistics plugin', 500); | ||||
|         } | ||||
|  | ||||
|         echo json_encode(['sent' => 0]); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Send the stats to the server. | ||||
|      * On first load | on demand mode it will show a message asking users to select mode. | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   3.5 | ||||
|      * | ||||
|      * @throws  \Exception         If user is not allowed. | ||||
|      * @throws  \RuntimeException  If there is an error saving the params, disabling the plugin or sending the data. | ||||
|      */ | ||||
|     public function onAjaxSendStats() | ||||
|     { | ||||
|         if (!$this->isAllowedUser() || !$this->isAjaxRequest()) { | ||||
|             throw new \Exception($this->getApplication()->getLanguage()->_('JGLOBAL_AUTH_ACCESS_DENIED'), 403); | ||||
|         } | ||||
|  | ||||
|         // User has not selected the mode. Show message. | ||||
|         if ((int) $this->params->get('mode') !== static::MODE_ALLOW_ALWAYS) { | ||||
|             $data = [ | ||||
|                 'sent' => 0, | ||||
|                 'html' => $this->getRenderer('message')->render($this->getLayoutData()), | ||||
|             ]; | ||||
|  | ||||
|             echo json_encode($data); | ||||
|  | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (!$this->saveParams()) { | ||||
|             throw new \RuntimeException('Unable to save plugin settings', 500); | ||||
|         } | ||||
|  | ||||
|         echo json_encode(['sent' => (int) $this->sendStats()]); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the data through events | ||||
|      * | ||||
|      * @param   string  $context  Context where this will be called from | ||||
|      * | ||||
|      * @return  array | ||||
|      * | ||||
|      * @since   3.5 | ||||
|      */ | ||||
|     public function onGetStatsData($context) | ||||
|     { | ||||
|         return $this->getStatsData(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Debug a layout of this plugin | ||||
|      * | ||||
|      * @param   string  $layoutId  Layout identifier | ||||
|      * @param   array   $data      Optional data for the layout | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   3.5 | ||||
|      */ | ||||
|     public function debug($layoutId, $data = []) | ||||
|     { | ||||
|         $data = array_merge($this->getLayoutData(), $data); | ||||
|  | ||||
|         return $this->getRenderer($layoutId)->debug($data); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the data for the layout | ||||
|      * | ||||
|      * @return  array | ||||
|      * | ||||
|      * @since   3.5 | ||||
|      */ | ||||
|     private function getLayoutData() | ||||
|     { | ||||
|         return [ | ||||
|             'plugin'       => $this, | ||||
|             'pluginParams' => $this->params, | ||||
|             'statsData'    => $this->getStatsData(), | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the layout paths | ||||
|      * | ||||
|      * @return  array | ||||
|      * | ||||
|      * @since   3.5 | ||||
|      */ | ||||
|     private function getLayoutPaths() | ||||
|     { | ||||
|         $template = $this->getApplication()->getTemplate(); | ||||
|  | ||||
|         return [ | ||||
|             JPATH_ADMINISTRATOR . '/templates/' . $template . '/html/layouts/plugins/' . $this->_type . '/' . $this->_name, | ||||
|             JPATH_PLUGINS . '/' . $this->_type . '/' . $this->_name . '/layouts', | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the plugin renderer | ||||
|      * | ||||
|      * @param   string  $layoutId  Layout identifier | ||||
|      * | ||||
|      * @return  \Joomla\CMS\Layout\LayoutInterface | ||||
|      * | ||||
|      * @since   3.5 | ||||
|      */ | ||||
|     private function getRenderer($layoutId = 'default') | ||||
|     { | ||||
|         $renderer = new FileLayout($layoutId); | ||||
|  | ||||
|         $renderer->setIncludePaths($this->getLayoutPaths()); | ||||
|  | ||||
|         return $renderer; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the data that will be sent to the stats server. | ||||
|      * | ||||
|      * @return  array | ||||
|      * | ||||
|      * @since   3.5 | ||||
|      */ | ||||
|     private function getStatsData() | ||||
|     { | ||||
|         $data = [ | ||||
|             'unique_id'   => $this->getUniqueId(), | ||||
|             'php_version' => PHP_VERSION, | ||||
|             'db_type'     => $this->getDatabase()->name, | ||||
|             'db_version'  => $this->getDatabase()->getVersion(), | ||||
|             'cms_version' => JVERSION, | ||||
|             'server_os'   => php_uname('s') . ' ' . php_uname('r'), | ||||
|         ]; | ||||
|  | ||||
|         // Check if we have a MariaDB version string and extract the proper version from it | ||||
|         if (preg_match('/^(?:5\.5\.5-)?(mariadb-)?(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)/i', $data['db_version'], $versionParts)) { | ||||
|             $data['db_version'] = $versionParts['major'] . '.' . $versionParts['minor'] . '.' . $versionParts['patch']; | ||||
|         } | ||||
|  | ||||
|         return $data; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the unique id. Generates one if none is set. | ||||
|      * | ||||
|      * @return  integer | ||||
|      * | ||||
|      * @since   3.5 | ||||
|      */ | ||||
|     private function getUniqueId() | ||||
|     { | ||||
|         if (null === $this->uniqueId) { | ||||
|             $this->uniqueId = $this->params->get('unique_id', hash('sha1', UserHelper::genRandomPassword(28) . time())); | ||||
|         } | ||||
|  | ||||
|         return $this->uniqueId; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Check if current user is allowed to send the data | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @since   3.5 | ||||
|      */ | ||||
|     private function isAllowedUser() | ||||
|     { | ||||
|         return $this->getApplication()->getIdentity() && $this->getApplication()->getIdentity()->authorise('core.admin'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Check if the debug is enabled | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @since   3.5 | ||||
|      */ | ||||
|     private function isDebugEnabled() | ||||
|     { | ||||
|         return \defined('PLG_SYSTEM_STATS_DEBUG'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Check if last_run + interval > now | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @since   3.5 | ||||
|      */ | ||||
|     private function isUpdateRequired() | ||||
|     { | ||||
|         $last     = (int) $this->params->get('lastrun', 0); | ||||
|         $interval = (int) $this->params->get('interval', 12); | ||||
|         $mode     = (int) $this->params->get('mode', 0); | ||||
|  | ||||
|         if ($mode === static::MODE_ALLOW_NEVER) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         // Never updated or debug enabled | ||||
|         if (!$last || $this->isDebugEnabled()) { | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         return abs(time() - $last) > $interval * 3600; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Check valid AJAX request | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @since   3.5 | ||||
|      */ | ||||
|     private function isAjaxRequest() | ||||
|     { | ||||
|         return strtolower($this->getApplication()->getInput()->server->get('HTTP_X_REQUESTED_WITH', '')) === 'xmlhttprequest'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Render a layout of this plugin | ||||
|      * | ||||
|      * @param   string  $layoutId  Layout identifier | ||||
|      * @param   array   $data      Optional data for the layout | ||||
|      * | ||||
|      * @return  string | ||||
|      * | ||||
|      * @since   3.5 | ||||
|      */ | ||||
|     public function render($layoutId, $data = []) | ||||
|     { | ||||
|         $data = array_merge($this->getLayoutData(), $data); | ||||
|  | ||||
|         return $this->getRenderer($layoutId)->render($data); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Save the plugin parameters | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @since   3.5 | ||||
|      */ | ||||
|     private function saveParams() | ||||
|     { | ||||
|         // Update params | ||||
|         $this->params->set('lastrun', time()); | ||||
|         $this->params->set('unique_id', $this->getUniqueId()); | ||||
|         $interval = (int) $this->params->get('interval', 12); | ||||
|         $this->params->set('interval', $interval ?: 12); | ||||
|  | ||||
|         $paramsJson = $this->params->toString('JSON'); | ||||
|         $db         = $this->getDatabase(); | ||||
|  | ||||
|         $query = $db->getQuery(true) | ||||
|             ->update($db->quoteName('#__extensions')) | ||||
|             ->set($db->quoteName('params') . ' = :params') | ||||
|             ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')) | ||||
|             ->where($db->quoteName('folder') . ' = ' . $db->quote('system')) | ||||
|             ->where($db->quoteName('element') . ' = ' . $db->quote('stats')) | ||||
|             ->bind(':params', $paramsJson); | ||||
|  | ||||
|         try { | ||||
|             // Lock the tables to prevent multiple plugin executions causing a race condition | ||||
|             $db->lockTable('#__extensions'); | ||||
|         } catch (\Exception $e) { | ||||
|             // If we can't lock the tables it's too risky to continue execution | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|             // Update the plugin parameters | ||||
|             $result = $db->setQuery($query)->execute(); | ||||
|  | ||||
|             $this->clearCacheGroups(['com_plugins']); | ||||
|         } catch (\Exception $exc) { | ||||
|             // If we failed to execute | ||||
|             $db->unlockTables(); | ||||
|             $result = false; | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|             // Unlock the tables after writing | ||||
|             $db->unlockTables(); | ||||
|         } catch (\Exception $e) { | ||||
|             // If we can't lock the tables assume we have somehow failed | ||||
|             $result = false; | ||||
|         } | ||||
|  | ||||
|         return $result; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Send the stats to the stats server | ||||
|      * | ||||
|      * @return  boolean | ||||
|      * | ||||
|      * @since   3.5 | ||||
|      * | ||||
|      * @throws  \RuntimeException  If there is an error sending the data and debug mode enabled. | ||||
|      */ | ||||
|     private function sendStats() | ||||
|     { | ||||
|         $error = false; | ||||
|  | ||||
|         try { | ||||
|             // Don't let the request take longer than 2 seconds to avoid page timeout issues | ||||
|             $response = HttpFactory::getHttp()->post($this->serverUrl, $this->getStatsData(), [], 2); | ||||
|  | ||||
|             if (!$response) { | ||||
|                 $error = 'Could not send site statistics to remote server: No response'; | ||||
|             } elseif ($response->code !== 200) { | ||||
|                 $data = json_decode($response->body); | ||||
|  | ||||
|                 $error = 'Could not send site statistics to remote server: ' . $data->message; | ||||
|             } | ||||
|         } catch (\UnexpectedValueException $e) { | ||||
|             // There was an error sending stats. Should we do anything? | ||||
|             $error = 'Could not send site statistics to remote server: ' . $e->getMessage(); | ||||
|         } catch (\RuntimeException $e) { | ||||
|             // There was an error connecting to the server or in the post request | ||||
|             $error = 'Could not connect to statistics server: ' . $e->getMessage(); | ||||
|         } catch (\Exception $e) { | ||||
|             // An unexpected error in processing; don't let this failure kill the site | ||||
|             $error = 'Unexpected error connecting to statistics server: ' . $e->getMessage(); | ||||
|         } | ||||
|  | ||||
|         if ($error !== false) { | ||||
|             // Log any errors if logging enabled. | ||||
|             Log::add($error, Log::WARNING, 'jerror'); | ||||
|  | ||||
|             // If Stats debug mode enabled, or Global Debug mode enabled, show error to the user. | ||||
|             if ($this->isDebugEnabled() || $this->getApplication()->get('debug')) { | ||||
|                 throw new \RuntimeException($error, 500); | ||||
|             } | ||||
|  | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Clears cache groups. We use it to clear the plugins cache after we update the last run timestamp. | ||||
|      * | ||||
|      * @param   array  $clearGroups  The cache groups to clean | ||||
|      * | ||||
|      * @return  void | ||||
|      * | ||||
|      * @since   3.5 | ||||
|      */ | ||||
|     private function clearCacheGroups(array $clearGroups) | ||||
|     { | ||||
|         foreach ($clearGroups as $group) { | ||||
|             try { | ||||
|                 $options = [ | ||||
|                     'defaultgroup' => $group, | ||||
|                     'cachebase'    => $this->getApplication()->get('cache_path', JPATH_CACHE), | ||||
|                 ]; | ||||
|  | ||||
|                 $cache = Cache::getInstance('callback', $options); | ||||
|                 $cache->clean(); | ||||
|             } catch (\Exception $e) { | ||||
|                 // Ignore it | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Disable this plugin, if user selects once or never, to stop Joomla loading the plugin on every page load and | ||||
|      * therefore regaining a tiny bit of performance | ||||
|      * | ||||
|      * @since   4.0.0 | ||||
|      * | ||||
|      * @return  boolean | ||||
|      */ | ||||
|     private function disablePlugin() | ||||
|     { | ||||
|         $db = $this->getDatabase(); | ||||
|  | ||||
|         $query = $db->getQuery(true) | ||||
|             ->update($db->quoteName('#__extensions')) | ||||
|             ->set($db->quoteName('enabled') . ' = 0') | ||||
|             ->where($db->quoteName('type') . ' = ' . $db->quote('plugin')) | ||||
|             ->where($db->quoteName('folder') . ' = ' . $db->quote('system')) | ||||
|             ->where($db->quoteName('element') . ' = ' . $db->quote('stats')); | ||||
|  | ||||
|         try { | ||||
|             // Lock the tables to prevent multiple plugin executions causing a race condition | ||||
|             $db->lockTable('#__extensions'); | ||||
|         } catch (\Exception $e) { | ||||
|             // If we can't lock the tables it's too risky to continue execution | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|             // Update the plugin parameters | ||||
|             $result = $db->setQuery($query)->execute(); | ||||
|  | ||||
|             $this->clearCacheGroups(['com_plugins']); | ||||
|         } catch (\Exception $exc) { | ||||
|             // If we failed to execute | ||||
|             $db->unlockTables(); | ||||
|             $result = false; | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|             // Unlock the tables after writing | ||||
|             $db->unlockTables(); | ||||
|         } catch (\Exception $e) { | ||||
|             // If we can't lock the tables assume we have somehow failed | ||||
|             $result = false; | ||||
|         } | ||||
|  | ||||
|         return $result; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Are we in a Multi-factor Authentication page? | ||||
|      * | ||||
|      * @return  bool | ||||
|      * @since   4.2.1 | ||||
|      */ | ||||
|     private function isCaptiveMFA(): bool | ||||
|     { | ||||
|         return method_exists($this->getApplication(), 'isMultiFactorAuthenticationPage') | ||||
|             && $this->getApplication()->isMultiFactorAuthenticationPage(true); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										44
									
								
								plugins/system/stats/src/Field/AbstractStatsField.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								plugins/system/stats/src/Field/AbstractStatsField.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,44 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Plugin | ||||
|  * @subpackage  System.stats | ||||
|  * | ||||
|  * @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\Plugin\System\Stats\Field; | ||||
|  | ||||
| use Joomla\CMS\Factory; | ||||
| use Joomla\CMS\Form\FormField; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Base field for the Stats Plugin. | ||||
|  * | ||||
|  * @since  3.5 | ||||
|  */ | ||||
| abstract class AbstractStatsField extends FormField | ||||
| { | ||||
|     /** | ||||
|      * Get the layouts paths | ||||
|      * | ||||
|      * @return  array | ||||
|      * | ||||
|      * @since   3.5 | ||||
|      */ | ||||
|     protected function getLayoutPaths() | ||||
|     { | ||||
|         $template = Factory::getApplication()->getTemplate(); | ||||
|  | ||||
|         return [ | ||||
|             JPATH_ADMINISTRATOR . '/templates/' . $template . '/html/layouts/plugins/system/stats', | ||||
|             JPATH_PLUGINS . '/system/stats/layouts', | ||||
|             JPATH_SITE . '/layouts', | ||||
|         ]; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										62
									
								
								plugins/system/stats/src/Field/DataField.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								plugins/system/stats/src/Field/DataField.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,62 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Plugin | ||||
|  * @subpackage  System.stats | ||||
|  * | ||||
|  * @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\Plugin\System\Stats\Field; | ||||
|  | ||||
| use Joomla\CMS\Factory; | ||||
| use Joomla\CMS\Plugin\PluginHelper; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Unique ID Field class for the Stats Plugin. | ||||
|  * | ||||
|  * @since  3.5 | ||||
|  */ | ||||
| class DataField extends AbstractStatsField | ||||
| { | ||||
|     /** | ||||
|      * The form field type. | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  3.5 | ||||
|      */ | ||||
|     protected $type = 'Data'; | ||||
|  | ||||
|     /** | ||||
|      * Name of the layout being used to render the field | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  3.5 | ||||
|      */ | ||||
|     protected $layout = 'field.data'; | ||||
|  | ||||
|     /** | ||||
|      * Method to get the data to be passed to the layout for rendering. | ||||
|      * | ||||
|      * @return  array | ||||
|      * | ||||
|      * @since   3.5 | ||||
|      */ | ||||
|     protected function getLayoutData() | ||||
|     { | ||||
|         $data       = parent::getLayoutData(); | ||||
|  | ||||
|         PluginHelper::importPlugin('system', 'stats'); | ||||
|  | ||||
|         $result = Factory::getApplication()->triggerEvent('onGetStatsData', ['stats.field.data']); | ||||
|  | ||||
|         $data['statsData'] = $result ? reset($result) : []; | ||||
|  | ||||
|         return $data; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										39
									
								
								plugins/system/stats/src/Field/UniqueidField.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								plugins/system/stats/src/Field/UniqueidField.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,39 @@ | ||||
| <?php | ||||
|  | ||||
| /** | ||||
|  * @package     Joomla.Plugin | ||||
|  * @subpackage  System.stats | ||||
|  * | ||||
|  * @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\Plugin\System\Stats\Field; | ||||
|  | ||||
| // phpcs:disable PSR1.Files.SideEffects | ||||
| \defined('_JEXEC') or die; | ||||
| // phpcs:enable PSR1.Files.SideEffects | ||||
|  | ||||
| /** | ||||
|  * Unique ID Field class for the Stats Plugin. | ||||
|  * | ||||
|  * @since  3.5 | ||||
|  */ | ||||
| class UniqueidField extends AbstractStatsField | ||||
| { | ||||
|     /** | ||||
|      * The form field type. | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  3.5 | ||||
|      */ | ||||
|     protected $type = 'Uniqueid'; | ||||
|  | ||||
|     /** | ||||
|      * Name of the layout being used to render the field | ||||
|      * | ||||
|      * @var    string | ||||
|      * @since  3.5 | ||||
|      */ | ||||
|     protected $layout = 'field.uniqueid'; | ||||
| } | ||||
		Reference in New Issue
	
	Block a user