diff options
-rw-r--r-- | lang/en.json | 5 | ||||
-rw-r--r-- | plugins/Live/API.php | 41 | ||||
-rw-r--r-- | plugins/Live/javascripts/visitorProfile.js | 4 | ||||
-rw-r--r-- | plugins/Live/stylesheets/visitor_profile.less | 20 | ||||
-rw-r--r-- | plugins/Live/templates/_actionsList.twig | 15 | ||||
-rw-r--r-- | plugins/Live/templates/getVisitList.twig | 2 | ||||
-rw-r--r-- | plugins/Live/templates/getVisitorProfilePopup.twig | 25 | ||||
-rw-r--r-- | tests/PHPUnit/Integration/expected/test_periodIsRange_dateIsLastN_MetadataAndNormalAPI__Live.getVisitorProfile.xml | 81 | ||||
-rwxr-xr-x | tests/PHPUnit/IntegrationTestCase.php | 3 |
9 files changed, 123 insertions, 73 deletions
diff --git a/lang/en.json b/lang/en.json index c0b721eb7f..74cc3ead5e 100644 --- a/lang/en.json +++ b/lang/en.json @@ -1142,8 +1142,9 @@ "NoMoreVisits_js": "There are no more visits for this visitor.", "PreviousVisitor": "Previous visitor", "NextVisitor": "Next visitor", - "ShowMap_js": "Show map", - "HideMap_js": "Hide map" + "ShowMap_js": "show map", + "HideMap_js": "hide map", + "VisitsFrom": "%1$s%2$s visits%3$s from" }, "Login": { "PluginDescription": "Login Authentication plugin, reading the credentials from the config\/config.inc.php file for the Super User, and from the Database for the other users. Can be easily replaced to introduce a new Authentication mechanism (OpenID, htaccess, custom Auth, etc.).", diff --git a/plugins/Live/API.php b/plugins/Live/API.php index 7b7844d346..e967f3fdc7 100644 --- a/plugins/Live/API.php +++ b/plugins/Live/API.php @@ -31,7 +31,7 @@ use Piwik\Plugins\Live\Visitor; use Piwik\Plugins\SitesManager\API as SitesManagerAPI; /** - * @see plugins/Referers/functions.php + * @see plugins/Live/Visitor.php */ require_once PIWIK_INCLUDE_PATH . '/plugins/Live/Visitor.php'; @@ -248,12 +248,36 @@ class API } } - $countries[] = $visit->getColumn('countryCode'); - $continents[] = $visit->getColumn('continentCode'); + $countryCode = $visit->getColumn('countryCode'); + if (!isset($countries[$countryCode])) { + $countries[$countryCode] = 0; + } + ++$countries[$countryCode]; + + $continentCode = $visit->getColumn('continentCode'); + if (!isset($continents[$continentCode])) { + $continents[$continentCode] = 0; + } + ++$continents[$continentCode]; } - $result['countries'] = implode(',', array_unique($countries)); - $result['continents'] = implode(',', array_unique($continents)); + // sort countries/continents by visit + asort($countries); + asort($continents); + + // transform country/continents into something that will look good in XML + $result['countries'] = $result['continents'] = array(); + foreach ($countries as $countryCode => $nbVisits) { + $result['countries'][] = array('country' => $countryCode, + 'nb_visits' => $nbVisits, + 'flag' => \Piwik\Plugins\UserCountry\getFlagFromCode($countryCode), + 'prettyName' => \Piwik\Plugins\UserCountry\countryTranslate($countryCode)); + } + foreach ($continents as $continentCode => $nbVisits) { + $result['continents'][] = array('continent' => $continentCode, + 'nb_visits' => $nbVisits, + 'prettyName' => \Piwik\Plugins\UserCountry\continentTranslate($continentCode)); + } $result['totalVisitDurationPretty'] = Piwik::getPrettyTimeFromSeconds($result['totalVisitDuration']); @@ -270,9 +294,12 @@ class API $timezone = Site::getTimezoneFor($idSite); foreach ($result['lastVisits']->getRows() as $visit) { $dateTimeVisitFirstAction = Date::factory($visit->getColumn('firstActionTimestamp'), $timezone); - $dateTimePretty = $dateTimeVisitFirstAction->getLocalized(self::VISITOR_PROFILE_DATE_FORMAT); - $visit->setColumn('serverDatePrettyFirstAction', $dateTimePretty); + $datePretty = $dateTimeVisitFirstAction->getLocalized(self::VISITOR_PROFILE_DATE_FORMAT); + $visit->setColumn('serverDatePrettyFirstAction', $datePretty); + + $dateTimePretty = $datePretty . ' ' . $visit->getColumn('serverTimePrettyFirstAction'); + $visit->setColumn('serverDateTimePrettyFirstAction', $dateTimePretty); } // get visitor IDs that are adjacent to this one in log_visit diff --git a/plugins/Live/javascripts/visitorProfile.js b/plugins/Live/javascripts/visitorProfile.js index 3137af7f65..8d9b4ad73d 100644 --- a/plugins/Live/javascripts/visitorProfile.js +++ b/plugins/Live/javascripts/visitorProfile.js @@ -118,11 +118,13 @@ $map.slideDown('slow'); var newLabel = 'Live_HideMap_js'; + + piwikHelper.lazyScrollTo($('.visitor-profile-location', $element)[0], 400, true); } else { $map.slideUp('slow'); var newLabel = 'Live_ShowMap_js'; } - $('a', this).text(_pk_translate(newLabel)); + $(this).text(_pk_translate(newLabel)); return false; }); diff --git a/plugins/Live/stylesheets/visitor_profile.less b/plugins/Live/stylesheets/visitor_profile.less index e296af8058..fafb12f02a 100644 --- a/plugins/Live/stylesheets/visitor_profile.less +++ b/plugins/Live/stylesheets/visitor_profile.less @@ -219,7 +219,7 @@ } .visitor-profile-map { - padding:unit(@visitor_profile_map_pad_top, px) 21px 4px 21px; + padding:0 21px 13px 21px; .dataTableFeatures,.no_data { display:none !important; @@ -232,16 +232,8 @@ } .visitor-profile-show-map { - height:auto; - width:100%; - display:block; - text-align:center; - padding-bottom:unit(@visitor_profile_map_pad_bottom, px); - - > a { - font-size:14px; - font-weight:bold; - } + font-size:13px; + font-style:italic; } .visitor-profile-summary,.visitor-profile-important-visits { @@ -266,7 +258,6 @@ } .visitor-profile-important-visits { - > div { float:left; width:265px; @@ -284,6 +275,11 @@ .visitor-profile-location { padding:10px 0 4px 19px; + + p { + margin:13px 0; + font-size:14px; + } } .visitor-profile-pages-visited { diff --git a/plugins/Live/templates/_actionsList.twig b/plugins/Live/templates/_actionsList.twig index 2caf10b017..27eee7c250 100644 --- a/plugins/Live/templates/_actionsList.twig +++ b/plugins/Live/templates/_actionsList.twig @@ -12,10 +12,17 @@ {% endset %} {% if not javascriptVariablesToSet.filterEcommerce or action.type == 'ecommerceOrder' or action.type == 'ecommerceAbandonedCart' %} <li class="{% if action.goalName is defined %}goal{% else %}action{% endif %}" - title="{{ action.serverTimePretty }}{% if action.url is defined and action.url|trim|length -%} - {{- action.url }}{% endif %}{% if customVariablesTooltip|trim|length %} {{ customVariablesTooltip|trim }}{% endif -%} - {%- if action.timeSpentPretty is defined -%} {{ 'General_TimeOnPage'|translate }}: {{ action.timeSpentPretty|raw }}{% endif -%} - {%- if action.generationTime is defined %} {{ 'General_ColumnGenerationTime'|translate }}: {{ action.generationTime|raw }}{% endif %}"> + title="{{ action.serverTimePretty }}{% if action.url is defined and action.url|trim|length %} + +{{ action.url }}{% endif %}{% if customVariablesTooltip|trim|length %} + +{{ customVariablesTooltip|trim }}{% endif -%} + {%- if action.timeSpentPretty is defined %} + +{{ 'General_TimeOnPage'|translate }}: {{ action.timeSpentPretty|raw }}{% endif -%} + {%- if action.generationTime is defined %} + +{{ 'General_ColumnGenerationTime'|translate }}: {{ action.generationTime|raw }}{% endif %}"> {% if action.type == 'ecommerceOrder' or action.type == 'ecommerceAbandonedCart' %} {# Ecommerce Abandoned Cart / Ecommerce Order #} <img src="{{ action.icon }}"/> diff --git a/plugins/Live/templates/getVisitList.twig b/plugins/Live/templates/getVisitList.twig index 8794709576..df6ca02ccf 100644 --- a/plugins/Live/templates/getVisitList.twig +++ b/plugins/Live/templates/getVisitList.twig @@ -1,7 +1,7 @@ {% for visitInfo in visits.getRows() %} <li> <div> - <h2 class="visitor-profile-visit-title" data-idvisit="{{ visitInfo.getColumn('idVisit') }}">{{ 'General_Visit'|translate }} #{{ startCounter }}</h2><span> - ({{ visitInfo.getColumn('visitDurationPretty')|raw }})</span><span class="visitor-profile-date">{{ visitInfo.getColumn('serverDatePrettyFirstAction') }}</span> + <h2 class="visitor-profile-visit-title" data-idvisit="{{ visitInfo.getColumn('idVisit') }}">{{ 'General_Visit'|translate }} #{{ startCounter }}</h2>{% if visitInfo.getColumn('visitDuration') != 0 %}<span> - ({{ visitInfo.getColumn('visitDurationPretty')|raw }})</span>{% endif %}<span class="visitor-profile-date" title="{{ visitInfo.getColumn('serverDateTimePrettyFirstAction') }}">{{ visitInfo.getColumn('serverDatePrettyFirstAction') }}</span> <ol class="visitor-profile-actions"> {% include "@Live/_actionsList.twig" with {'actionDetails': visitInfo.getColumn('actionDetails'), 'javascriptVariablesToSet': { diff --git a/plugins/Live/templates/getVisitorProfilePopup.twig b/plugins/Live/templates/getVisitorProfilePopup.twig index 5bb9d8be6b..1635aaab38 100644 --- a/plugins/Live/templates/getVisitorProfilePopup.twig +++ b/plugins/Live/templates/getVisitorProfilePopup.twig @@ -3,7 +3,6 @@ data-visitor-id="{{ visitorData.lastVisits.getFirstRow().getColumn('visitorId') }}" data-next-visitor="{{ visitorData.nextVisitorId }}" data-prev-visitor="{{ visitorData.prevVisitorId }}" - data-continents="{{ visitorData.continents }}" tabindex="0"> <a href class="visitor-profile-close"></a> <div class="visitor-profile-info"> @@ -29,12 +28,6 @@ </div> <p style="clear:both"/> </div> - <div> - <div class="visitor-profile-location"> - <h1>{{ 'UserCountry_Location'|translate }}</h1> - {{ lastVisitsChart|raw }} - </div> - </div> <div class="visitor-profile-summary"> <h1>{{ 'General_Summary'|translate }}</h1> <div> @@ -68,11 +61,19 @@ </div> </div> </div> - <div class="visitor-profile-map" style="display:none"> - {{ userCountryMap|raw }} - </div> - <div class="visitor-profile-show-map"> - <a href="#">{{ 'Live_ShowMap_js'|translate }}</a> + <div> + <div class="visitor-profile-location"> + <h1>{{ 'UserCountry_Location'|translate }}</h1> + <p> + {%- for entry in visitorData.countries -%} + {{- 'Live_VisitsFrom'|translate('<strong>', entry.nb_visits, '</strong>')|raw }} <img src="{{ entry.flag }}"/> {{ entry.prettyName }}{% if not loop.last %}, {% endif %} + {%- endfor %} + <a class="visitor-profile-show-map" href="#">({{ 'Live_ShowMap_js'|translate }})</a> + </p> + <div class="visitor-profile-map" style="display:none"> + {{ userCountryMap|raw }} + </div> + </div> </div> </div> <div class="visitor-profile-visits-info"> diff --git a/tests/PHPUnit/Integration/expected/test_periodIsRange_dateIsLastN_MetadataAndNormalAPI__Live.getVisitorProfile.xml b/tests/PHPUnit/Integration/expected/test_periodIsRange_dateIsLastN_MetadataAndNormalAPI__Live.getVisitorProfile.xml index 7d6129788c..3e9aa5413f 100644 --- a/tests/PHPUnit/Integration/expected/test_periodIsRange_dateIsLastN_MetadataAndNormalAPI__Live.getVisitorProfile.xml +++ b/tests/PHPUnit/Integration/expected/test_periodIsRange_dateIsLastN_MetadataAndNormalAPI__Live.getVisitorProfile.xml @@ -7,18 +7,31 @@ <totalConversionsByGoal> <row key="1">1</row> </totalConversionsByGoal> - <countries>fr</countries> - <continents>eur</continents> + <continents> + <row> + <continent>eur</continent> + <nb_visits>2</nb_visits> + <prettyName>Europe</prettyName> + </row> + </continents> + <countries> + <row> + <country>fr</country> + <nb_visits>2</nb_visits> + <flag>plugins/UserCountry/images/flags/fr.png</flag> + <prettyName>France</prettyName> + </row> + </countries> <totalVisitDurationPretty>6 min 1s</totalVisitDurationPretty> <firstVisit> - <date>2013-08-29</date> - <prettyDate>29 Aug 2013</prettyDate> + + <daysAgo>0</daysAgo> <referralSummary>Direct Entry</referralSummary> </firstVisit> <lastVisit> - <date>2013-08-29</date> - <prettyDate>29 Aug 2013</prettyDate> + + <daysAgo>0</daysAgo> <referralSummary>Direct Entry</referralSummary> </lastVisit> @@ -27,7 +40,7 @@ <idSite>1</idSite> <idVisit>3</idVisit> <visitIp>156.5.3.2</visitIp> - <visitorId>61e8cc2d51fea26d</visitorId> + <visitorType>new</visitorType> <visitorTypeIcon /> <visitConverted>0</visitConverted> @@ -43,7 +56,7 @@ <pageTitle /> <pageIdAction>6</pageIdAction> <pageId>5</pageId> - <serverTimePretty>Thu 29 Aug 10:35:33</serverTimePretty> + <icon>plugins/Zeitgeist/images/link.gif</icon> </row> </actionDetails> @@ -60,13 +73,13 @@ <goalConversions>0</goalConversions> <siteCurrency>USD</siteCurrency> <siteCurrencySymbol>$</siteCurrencySymbol> - <serverDate>2013-08-29</serverDate> + <visitLocalTime>12:34:06</visitLocalTime> <visitLocalHour>12</visitLocalHour> - <visitServerHour>10</visitServerHour> - <firstActionTimestamp>1377772533</firstActionTimestamp> - <lastActionTimestamp>1377772533</lastActionTimestamp> - <lastActionDateTime>2013-08-29 10:35:33</lastActionDateTime> + + + + <visitDuration>0</visitDuration> <visitDurationPretty>0s</visitDurationPretty> <visitCount>1</visitCount> @@ -120,17 +133,18 @@ <pluginName>java</pluginName> </row> </pluginsIcons> - <serverTimestamp>1377772533</serverTimestamp> - <serverTimePretty>10:35:33</serverTimePretty> - <serverDatePretty>Thu 29 Aug</serverDatePretty> - <serverDatePrettyFirstAction>29 Aug 2013</serverDatePrettyFirstAction> - <serverTimePrettyFirstAction>10:35:33</serverTimePrettyFirstAction> + + + + + + <serverDateTimePrettyFirstAction>4 Sep 2013 16:55:17</serverDateTimePrettyFirstAction> </row> <row> <idSite>1</idSite> <idVisit>2</idVisit> <visitIp>156.5.3.2</visitIp> - <visitorId>61e8cc2d51fea26d</visitorId> + <visitorType>new</visitorType> <visitorTypeIcon /> <visitConverted>1</visitConverted> @@ -146,7 +160,7 @@ <goalId>1</goalId> <revenue>0</revenue> <goalPageId /> - <serverTimePretty>Thu 29 Aug 09:35:33</serverTimePretty> + <url>http://example.org/homepage</url> <icon>plugins/Zeitgeist/images/goal.png</icon> </row> @@ -156,7 +170,7 @@ <pageTitle>Homepage</pageTitle> <pageIdAction>2</pageIdAction> <pageId>4</pageId> - <serverTimePretty>Thu 29 Aug 09:41:33</serverTimePretty> + <icon /> </row> </actionDetails> @@ -173,13 +187,13 @@ <goalConversions>1</goalConversions> <siteCurrency>USD</siteCurrency> <siteCurrencySymbol>$</siteCurrencySymbol> - <serverDate>2013-08-29</serverDate> + <visitLocalTime>12:34:06</visitLocalTime> <visitLocalHour>12</visitLocalHour> - <visitServerHour>9</visitServerHour> - <firstActionTimestamp>1377768933</firstActionTimestamp> - <lastActionTimestamp>1377769293</lastActionTimestamp> - <lastActionDateTime>2013-08-29 09:41:33</lastActionDateTime> + + + + <visitDuration>361</visitDuration> <visitDurationPretty>6 min 1s</visitDurationPretty> <visitCount>1</visitCount> @@ -233,13 +247,14 @@ <pluginName>java</pluginName> </row> </pluginsIcons> - <serverTimestamp>1377769293</serverTimestamp> - <serverTimePretty>09:41:33</serverTimePretty> - <serverDatePretty>Thu 29 Aug</serverDatePretty> - <serverDatePrettyFirstAction>29 Aug 2013</serverDatePrettyFirstAction> - <serverTimePrettyFirstAction>09:35:33</serverTimePrettyFirstAction> + + + + + + <serverDateTimePrettyFirstAction>4 Sep 2013 15:55:17</serverDateTimePrettyFirstAction> </row> </lastVisits> - <nextVisitorId>df7630bf363ed030</nextVisitorId> - <prevVisitorId>0</prevVisitorId> + + </result>
\ No newline at end of file diff --git a/tests/PHPUnit/IntegrationTestCase.php b/tests/PHPUnit/IntegrationTestCase.php index 44d1854855..e029abdc01 100755 --- a/tests/PHPUnit/IntegrationTestCase.php +++ b/tests/PHPUnit/IntegrationTestCase.php @@ -845,7 +845,8 @@ abstract class IntegrationTestCase extends PHPUnit_Framework_TestCase 'prevVisitorId', 'visitServerHour', 'date', - 'prettyDate' + 'prettyDate', + 'serverDateTimePrettyFirstAction' ); foreach ($toRemove as $xml) { $input = $this->removeXmlElement($input, $xml); |