Skip to content
Extraits de code Groupes Projets
Metrics.php 16,3 ko
Newer Older
  • Learn to ignore specific revisions
  •  * Piwik - free/libre analytics platform
    
     *
     * @link http://piwik.org
     * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
     *
     */
    
    use Piwik\Cache\LanguageAwareStaticCache;
    
    mattab's avatar
    mattab a validé
    require_once PIWIK_INCLUDE_PATH . "/core/Piwik.php";
    
    
     * This class contains metadata regarding core metrics and contains several
     * related helper functions.
    
     * Of note are the `INDEX_...` constants. In the database, metric column names
    
     * in {@link DataTable} rows are stored as integers to save space. The integer
    
     * values used are determined by these constants.
    
         * When saving DataTables in the DB, we replace all columns name with these IDs. This saves many bytes,
         * eg. INDEX_NB_UNIQ_VISITORS is an integer: 4 bytes, but 'nb_uniq_visitors' is 16 bytes at least
         */
        const INDEX_NB_UNIQ_VISITORS = 1;
        const INDEX_NB_VISITS = 2;
        const INDEX_NB_ACTIONS = 3;
        const INDEX_MAX_ACTIONS = 4;
        const INDEX_SUM_VISIT_LENGTH = 5;
        const INDEX_BOUNCE_COUNT = 6;
        const INDEX_NB_VISITS_CONVERTED = 7;
        const INDEX_NB_CONVERSIONS = 8;
        const INDEX_REVENUE = 9;
        const INDEX_GOALS = 10;
        const INDEX_SUM_DAILY_NB_UNIQ_VISITORS = 11;
    
        // Specific to the Actions reports
        const INDEX_PAGE_NB_HITS = 12;
        const INDEX_PAGE_SUM_TIME_SPENT = 13;
        const INDEX_PAGE_EXIT_NB_UNIQ_VISITORS = 14;
        const INDEX_PAGE_EXIT_NB_VISITS = 15;
        const INDEX_PAGE_EXIT_SUM_DAILY_NB_UNIQ_VISITORS = 16;
        const INDEX_PAGE_ENTRY_NB_UNIQ_VISITORS = 17;
        const INDEX_PAGE_ENTRY_SUM_DAILY_NB_UNIQ_VISITORS = 18;
        const INDEX_PAGE_ENTRY_NB_VISITS = 19;
        const INDEX_PAGE_ENTRY_NB_ACTIONS = 20;
        const INDEX_PAGE_ENTRY_SUM_VISIT_LENGTH = 21;
        const INDEX_PAGE_ENTRY_BOUNCE_COUNT = 22;
    
        // Ecommerce Items reports
        const INDEX_ECOMMERCE_ITEM_REVENUE = 23;
        const INDEX_ECOMMERCE_ITEM_QUANTITY = 24;
        const INDEX_ECOMMERCE_ITEM_PRICE = 25;
        const INDEX_ECOMMERCE_ORDERS = 26;
        const INDEX_ECOMMERCE_ITEM_PRICE_VIEWED = 27;
    
        // Site Search
        const INDEX_SITE_SEARCH_HAS_NO_RESULT = 28;
        const INDEX_PAGE_IS_FOLLOWING_SITE_SEARCH_NB_HITS = 29;
    
        // Performance Analytics
        const INDEX_PAGE_SUM_TIME_GENERATION = 30;
        const INDEX_PAGE_NB_HITS_WITH_TIME_GENERATION = 31;
        const INDEX_PAGE_MIN_TIME_GENERATION = 32;
        const INDEX_PAGE_MAX_TIME_GENERATION = 33;
    
    
        // Events
        const INDEX_EVENT_NB_HITS = 34;
        const INDEX_EVENT_SUM_EVENT_VALUE = 35;
        const INDEX_EVENT_MIN_EVENT_VALUE = 36;
        const INDEX_EVENT_MAX_EVENT_VALUE = 37;
    
        const INDEX_EVENT_NB_HITS_WITH_VALUE = 38;
    
        // Number of unique User IDs
        const INDEX_NB_USERS = 39;
    
        const INDEX_SUM_DAILY_NB_USERS = 40;
    
        // Goal reports
        const INDEX_GOAL_NB_CONVERSIONS = 1;
        const INDEX_GOAL_REVENUE = 2;
        const INDEX_GOAL_NB_VISITS_CONVERTED = 3;
        const INDEX_GOAL_ECOMMERCE_REVENUE_SUBTOTAL = 4;
        const INDEX_GOAL_ECOMMERCE_REVENUE_TAX = 5;
        const INDEX_GOAL_ECOMMERCE_REVENUE_SHIPPING = 6;
        const INDEX_GOAL_ECOMMERCE_REVENUE_DISCOUNT = 7;
        const INDEX_GOAL_ECOMMERCE_ITEMS = 8;
    
        public static $mappingFromIdToName = array(
    
            Metrics::INDEX_NB_UNIQ_VISITORS                      => 'nb_uniq_visitors',
            Metrics::INDEX_NB_VISITS                             => 'nb_visits',
            Metrics::INDEX_NB_ACTIONS                            => 'nb_actions',
    
            Metrics::INDEX_NB_USERS                              => 'nb_users',
    
            Metrics::INDEX_MAX_ACTIONS                           => 'max_actions',
            Metrics::INDEX_SUM_VISIT_LENGTH                      => 'sum_visit_length',
            Metrics::INDEX_BOUNCE_COUNT                          => 'bounce_count',
            Metrics::INDEX_NB_VISITS_CONVERTED                   => 'nb_visits_converted',
            Metrics::INDEX_NB_CONVERSIONS                        => 'nb_conversions',
            Metrics::INDEX_REVENUE                               => 'revenue',
            Metrics::INDEX_GOALS                                 => 'goals',
            Metrics::INDEX_SUM_DAILY_NB_UNIQ_VISITORS            => 'sum_daily_nb_uniq_visitors',
    
            Metrics::INDEX_SUM_DAILY_NB_UNIQ_VISITORS            => 'sum_daily_nb_users',
    
            Metrics::INDEX_PAGE_NB_HITS                          => 'nb_hits',
            Metrics::INDEX_PAGE_SUM_TIME_SPENT                   => 'sum_time_spent',
            Metrics::INDEX_PAGE_SUM_TIME_GENERATION              => 'sum_time_generation',
            Metrics::INDEX_PAGE_NB_HITS_WITH_TIME_GENERATION     => 'nb_hits_with_time_generation',
            Metrics::INDEX_PAGE_MIN_TIME_GENERATION              => 'min_time_generation',
            Metrics::INDEX_PAGE_MAX_TIME_GENERATION              => 'max_time_generation',
    
            Metrics::INDEX_PAGE_EXIT_NB_UNIQ_VISITORS            => 'exit_nb_uniq_visitors',
            Metrics::INDEX_PAGE_EXIT_NB_VISITS                   => 'exit_nb_visits',
            Metrics::INDEX_PAGE_EXIT_SUM_DAILY_NB_UNIQ_VISITORS  => 'sum_daily_exit_nb_uniq_visitors',
    
            Metrics::INDEX_PAGE_ENTRY_NB_UNIQ_VISITORS           => 'entry_nb_uniq_visitors',
            Metrics::INDEX_PAGE_ENTRY_SUM_DAILY_NB_UNIQ_VISITORS => 'sum_daily_entry_nb_uniq_visitors',
            Metrics::INDEX_PAGE_ENTRY_NB_VISITS                  => 'entry_nb_visits',
            Metrics::INDEX_PAGE_ENTRY_NB_ACTIONS                 => 'entry_nb_actions',
            Metrics::INDEX_PAGE_ENTRY_SUM_VISIT_LENGTH           => 'entry_sum_visit_length',
            Metrics::INDEX_PAGE_ENTRY_BOUNCE_COUNT               => 'entry_bounce_count',
            Metrics::INDEX_PAGE_IS_FOLLOWING_SITE_SEARCH_NB_HITS => 'nb_hits_following_search',
    
            Metrics::INDEX_ECOMMERCE_ITEM_REVENUE                => 'revenue',
            Metrics::INDEX_ECOMMERCE_ITEM_QUANTITY               => 'quantity',
            Metrics::INDEX_ECOMMERCE_ITEM_PRICE                  => 'price',
            Metrics::INDEX_ECOMMERCE_ITEM_PRICE_VIEWED           => 'price_viewed',
            Metrics::INDEX_ECOMMERCE_ORDERS                      => 'orders',
    
            Metrics::INDEX_EVENT_NB_HITS                         => 'nb_events',
    
            Metrics::INDEX_EVENT_SUM_EVENT_VALUE                 => 'sum_event_value',
            Metrics::INDEX_EVENT_MIN_EVENT_VALUE                 => 'min_event_value',
            Metrics::INDEX_EVENT_MAX_EVENT_VALUE                 => 'max_event_value',
    
            Metrics::INDEX_EVENT_NB_HITS_WITH_VALUE              => 'nb_events_with_value',
    
        public static $mappingFromIdToNameGoal = array(
    
            Metrics::INDEX_GOAL_NB_CONVERSIONS             => 'nb_conversions',
            Metrics::INDEX_GOAL_NB_VISITS_CONVERTED        => 'nb_visits_converted',
            Metrics::INDEX_GOAL_REVENUE                    => 'revenue',
            Metrics::INDEX_GOAL_ECOMMERCE_REVENUE_SUBTOTAL => 'revenue_subtotal',
            Metrics::INDEX_GOAL_ECOMMERCE_REVENUE_TAX      => 'revenue_tax',
            Metrics::INDEX_GOAL_ECOMMERCE_REVENUE_SHIPPING => 'revenue_shipping',
            Metrics::INDEX_GOAL_ECOMMERCE_REVENUE_DISCOUNT => 'revenue_discount',
            Metrics::INDEX_GOAL_ECOMMERCE_ITEMS            => 'items',
    
        protected static $metricsAggregatedFromLogs = array(
    
            Metrics::INDEX_NB_UNIQ_VISITORS,
            Metrics::INDEX_NB_VISITS,
            Metrics::INDEX_NB_ACTIONS,
    
            Metrics::INDEX_MAX_ACTIONS,
            Metrics::INDEX_SUM_VISIT_LENGTH,
            Metrics::INDEX_BOUNCE_COUNT,
            Metrics::INDEX_NB_VISITS_CONVERTED,
    
    Christian Raue's avatar
    Christian Raue a validé
        public static function getVisitsMetricNames()
    
    mattab's avatar
    mattab a validé
            foreach (self::$metricsAggregatedFromLogs as $metricId) {
    
                $names[$metricId] = self::$mappingFromIdToName[$metricId];
            }
            return $names;
        }
    
    
    Christian Raue's avatar
    Christian Raue a validé
        public static function getMappingFromIdToName()
    
        {
            $idToName = array_flip(self::$mappingFromIdToName);
            return $idToName;
        }
    
    
        /**
         * Is a lower value for a given column better?
         * @param $column
         * @return bool
         *
         * @ignore
         */
    
    Christian Raue's avatar
    Christian Raue a validé
        public static function isLowerValueBetter($column)
    
        {
            $lowerIsBetterPatterns = array(
                'bounce', 'exit'
            );
    
            foreach ($lowerIsBetterPatterns as $pattern) {
                if (strpos($column, $pattern) !== false) {
                    return true;
                }
            }
    
            return false;
        }
    
        /**
         * Derive the unit name from a column name
         * @param $column
         * @param $idSite
         * @return string
         * @ignore
         */
    
    Christian Raue's avatar
    Christian Raue a validé
        public static function getUnit($column, $idSite)
    
        {
            $nameToUnit = array(
                '_rate'   => '%',
    
                'revenue' => MetricsFormatter::getCurrencySymbol($idSite),
    
                '_time_'  => 's'
            );
    
            foreach ($nameToUnit as $pattern => $type) {
                if (strpos($column, $pattern) !== false) {
                    return $type;
                }
            }
    
            return '';
        }
    
    
    Christian Raue's avatar
    Christian Raue a validé
        public static function getDefaultMetricTranslations()
    
            $cache = new PluginAwareStaticCache('DefaultMetricTranslations');
    
            if ($cache->has()) {
                return $cache->get();
            }
    
    
            $translations = array(
    
                'label'                         => 'General_ColumnLabel',
                'date'                          => 'General_Date',
                'avg_time_on_page'              => 'General_ColumnAverageTimeOnPage',
                'sum_time_spent'                => 'General_ColumnSumVisitLength',
                'sum_visit_length'              => 'General_ColumnSumVisitLength',
                'bounce_count'                  => 'General_ColumnBounces',
                'bounce_count_returning'        => 'VisitFrequency_ColumnBounceCountForReturningVisits',
                'max_actions'                   => 'General_ColumnMaxActions',
                'max_actions_returning'         => 'VisitFrequency_ColumnMaxActionsInReturningVisit',
                'nb_visits_converted_returning' => 'VisitFrequency_ColumnNbReturningVisitsConverted',
                'sum_visit_length_returning'    => 'VisitFrequency_ColumnSumVisitLengthReturning',
                'nb_visits_converted'           => 'General_ColumnVisitsWithConversions',
                'nb_conversions'                => 'Goals_ColumnConversions',
    
                'revenue'                       => 'General_ColumnRevenue',
    
                'nb_hits'                       => 'General_ColumnPageviews',
                'entry_nb_visits'               => 'General_ColumnEntrances',
                'entry_nb_uniq_visitors'        => 'General_ColumnUniqueEntrances',
                'exit_nb_visits'                => 'General_ColumnExits',
                'exit_nb_uniq_visitors'         => 'General_ColumnUniqueExits',
                'entry_bounce_count'            => 'General_ColumnBounces',
                'exit_bounce_count'             => 'General_ColumnBounces',
    
                'exit_rate'                     => 'General_ColumnExitRate',
    
            $dailySum = ' (' . Piwik::translate('General_DailySum') . ')';
            $afterEntry = ' ' . Piwik::translate('General_AfterEntry');
    
            $translations['sum_daily_nb_uniq_visitors'] = Piwik::translate('General_ColumnNbUniqVisitors') . $dailySum;
    
            $translations['sum_daily_nb_users'] = Piwik::translate('General_ColumnNbUsers') . $dailySum;
    
            $translations['sum_daily_entry_nb_uniq_visitors'] = Piwik::translate('General_ColumnUniqueEntrances') . $dailySum;
            $translations['sum_daily_exit_nb_uniq_visitors'] = Piwik::translate('General_ColumnUniqueExits') . $dailySum;
            $translations['entry_nb_actions'] = Piwik::translate('General_ColumnNbActions') . $afterEntry;
            $translations['entry_sum_visit_length'] = Piwik::translate('General_ColumnSumVisitLength') . $afterEntry;
    
            $translations = array_merge(self::getDefaultMetrics(), self::getDefaultProcessedMetrics(), $translations);
    
            /**
             * Use this event to register translations for metrics processed by your plugin.
             *
             * @param string $translations The array mapping of column_name => Plugin_TranslationForColumn
             */
            Piwik::postEvent('Metrics.getDefaultMetricTranslations', array(&$translations));
    
    mattab's avatar
    mattab a validé
            $translations = array_map(array('\\Piwik\\Piwik','translate'), $translations);
    
    
            return $translations;
    
    Christian Raue's avatar
    Christian Raue a validé
        public static function getDefaultMetrics()
    
            $cache = new LanguageAwareStaticCache('DefaultMetrics');
    
            if ($cache->has()) {
                return $cache->get();
            }
    
    
            $translations = array(
                'nb_visits'        => 'General_ColumnNbVisits',
                'nb_uniq_visitors' => 'General_ColumnNbUniqVisitors',
                'nb_actions'       => 'General_ColumnNbActions',
    
                'nb_users'         => 'General_ColumnNbUsers',
    
    mattab's avatar
    mattab a validé
            $translations = array_map(array('\\Piwik\\Piwik','translate'), $translations);
    
            return $translations;
        }
    
    
    Christian Raue's avatar
    Christian Raue a validé
        public static function getDefaultProcessedMetrics()
    
    mattab's avatar
    mattab a validé
        {
    
            $cache = new LanguageAwareStaticCache('DefaultProcessedMetrics');
    
            if ($cache->has()) {
                return $cache->get();
            }
    
    
    mattab's avatar
    mattab a validé
            $translations = array(
                // Processed in AddColumnsProcessedMetrics
                'nb_actions_per_visit' => 'General_ColumnActionsPerVisit',
                'avg_time_on_site'     => 'General_ColumnAvgTimeOnSite',
                'bounce_rate'          => 'General_ColumnBounceRate',
                'conversion_rate'      => 'General_ColumnConversionRate',
            );
    
            $translations = array_map(array('\\Piwik\\Piwik','translate'), $translations);
    
            $cache->set($translations);
    
            return $translations;
    
    Christian Raue's avatar
    Christian Raue a validé
        public static function getReadableColumnName($columnIdRaw)
    
        {
            $mappingIdToName = self::$mappingFromIdToName;
    
            if (array_key_exists($columnIdRaw, $mappingIdToName)) {
    
                return $mappingIdToName[$columnIdRaw];
            }
    
            return $columnIdRaw;
        }
    
    
    Christian Raue's avatar
    Christian Raue a validé
        public static function getMetricIdsToProcessReportTotal()
    
        {
            return array(
    
                self::INDEX_NB_VISITS,
                self::INDEX_NB_UNIQ_VISITORS,
                self::INDEX_NB_ACTIONS,
                self::INDEX_PAGE_NB_HITS,
                self::INDEX_NB_VISITS_CONVERTED,
                self::INDEX_NB_CONVERSIONS,
                self::INDEX_BOUNCE_COUNT,
                self::INDEX_PAGE_ENTRY_BOUNCE_COUNT,
                self::INDEX_PAGE_ENTRY_NB_VISITS,
                self::INDEX_PAGE_ENTRY_NB_ACTIONS,
                self::INDEX_PAGE_EXIT_NB_VISITS,
    
                self::INDEX_PAGE_EXIT_NB_UNIQ_VISITORS,
                self::INDEX_REVENUE
    
    Christian Raue's avatar
    Christian Raue a validé
        public static function getDefaultMetricsDocumentation()
    
            $cache = new PluginAwareStaticCache('DefaultMetricsDocumentation');
    
            if ($cache->has()) {
                return $cache->get();
            }
    
    
    Thomas Steur's avatar
    Thomas Steur a validé
            $translations = array(
    
                'nb_visits'            => 'General_ColumnNbVisitsDocumentation',
                'nb_uniq_visitors'     => 'General_ColumnNbUniqVisitorsDocumentation',
                'nb_actions'           => 'General_ColumnNbActionsDocumentation',
    
                'nb_users'             => 'General_ColumnNbUsersDocumentation',
    
                'nb_actions_per_visit' => 'General_ColumnActionsPerVisitDocumentation',
                'avg_time_on_site'     => 'General_ColumnAvgTimeOnSiteDocumentation',
                'bounce_rate'          => 'General_ColumnBounceRateDocumentation',
                'conversion_rate'      => 'General_ColumnConversionRateDocumentation',
                'avg_time_on_page'     => 'General_ColumnAverageTimeOnPageDocumentation',
                'nb_hits'              => 'General_ColumnPageviewsDocumentation',
                'exit_rate'            => 'General_ColumnExitRateDocumentation'
            );
    
    Thomas Steur's avatar
    Thomas Steur a validé
            /**
             * Use this event to register translations for metrics documentation processed by your plugin.
             *
             * @param string[] $translations The array mapping of column_name => Plugin_TranslationForColumnDocumentation
             */
            Piwik::postEvent('Metrics.getDefaultMetricDocumentationTranslations', array(&$translations));
    
    
            $translations = array_map(array('\\Piwik\\Piwik','translate'), $translations);
    
            $cache->set($translations);
    
            return $translations;
    
    
        public static function getPercentVisitColumn()
        {
    
            $percentVisitsLabel = str_replace(' ', ' ', Piwik::translate('General_ColumnPercentageVisits'));