Skip to content
Extraits de code Groupes Projets
  • Thomas Steur's avatar
    0c9c30b7
    Better UI for Piwik 3, more responsive, faster, lots of other fixes (#10397) · 0c9c30b7
    Thomas Steur a rédigé
    * improved ui and responsiveness
    
    * improve rss widget
    
    * commit changes for ui again, got lost after the last commit
    
    * fix more tests
    
    * restoring files
    
    * fix fonts
    
    * fix more tests
    
    * more test fixes
    
    * fix some system tests
    
    * fix tests
    
    * fix system and ui tests
    
    * fix updater tests
    
    * make a page as loaded once the callback is called
    
    * enable verbose
    
    * more verbose output
    
    * enable phantomjs debug flag
    
    * debug should be a phantomjs option
    
    * trying to fix installation tests
    
    * fixes #10173 to not compile css files as less
    
    * trying to minimize js/css requests to hopefully prevent random ui test fails
    
    * disable verbose mode
    
    * fix updater and installation
    
    * lots of bugfixes and ui tweaks
    
    * fix reset dashboard
    
    * various bugfixes
    
    * fix integration tests
    
    * fix text color
    
    * hoping to fix installation tests this way
    
    * cache css/js resources for an hour, should speed up tests and prevent some random issues
    
    * we need to avoid installing plugins multiple times at the same time when requesting resources
    
    * finally getting the colors right again
    
    * fix most tests, more tests for theme
    
    * use an h2 element for titles for better accessibility
    
    * fix headline color
    
    * use actual theme text color (piwik-black)
    
    * fix small font size was applied on all p elements
    
    * fix tests
    
    * now improving all the datatables
    
    * trying to ignore images for visitor log
    
    * Revert "trying to ignore images for visitor log"
    
    This reverts commit ad1ff7267aae14ad905bef130e956c8593c4fb22.
    
    * fix tests
    
    * fix we had always ignored a max label width
    
    * trying to fix file permissions
    
    * fix more file permissions
    
    * Improved plugins update API (#10028)
    
    * refs #7983 let plugins add or remove fields to websites and better settings api
    
    * * Hide CorePluginsAdmin API methods
    * More documentation
    * Added some more tests
    
    * improved updates API for plugins
    
    * better error code as duplicate column cannot really happen when not actually renaming a colum
    
    Conflicts:
    	core/Updates/3.0.0-b1.php
    	plugins/CoreUpdater/Commands/Update/CliUpdateObserver.php
    
    * fix DB field piwik_log_visit.location_provider too small (#10003)
    
    * fixes #9564 fix DB field piwik_log_visit.location_provider too small
    
    * use new plugins updater API
    
    * DB field piwik_log_visit.visit_total_actions too small (#10002)
    
    * fixes #9565 DB field piwik_log_visit.visit_total_actions too small
    
    * change type of some db columns that are too small
    
    * fix tests (#10040)
    Conflicts:
    	plugins/CoreAdminHome/Menu.php
    	plugins/Goals/Menu.php
    	plugins/MobileMessaging/Menu.php
    	plugins/SitesManager/Menu.php
    	plugins/UsersManager/Menu.php
    	tests/PHPUnit/System/expected/test_apiGetReportMetadata__API.getWidgetMetadata.xml
    
    * fix more file permissions
    
    * repair more file permissions
    
    * repair more file permissions
    
    * trying to make ui tests work again, the table was missing
    
    * fix some encoding issues
    
    * cross browser fixes and usability improvement
    
    * move back the config icon, need to find a better solution later
    
    * more cross browser fixes
    
    * bugfixes
    
    * fix ui tests
    
    * fix encoding issue
    
    * fix various issues with the ui tests when a test gets aborted
    
    * also skip this visitor log test when aborted
    
    * there were 3 css files that were loaded separately, merge them instead into one css
    
    * forgot to add the actual manifest
    
    * do not add manifest if custom logo is specified
    
    * load font css files first as it was before merging them into big css
    
    * fix link icon was not aligned anymore
    
    * minor fixes
    
    * setting it back to 4px
    
    * in popovers the font variable was always ignored and a different font loaded
    
    * forgot to update screenshots
    
    * fix remaining tests
    
    * this should fix an update error
    
    * added 3 new widgets system check, system summary and plugin updates
    
    * tweak new widgets content
    
    * no page reload when changing date or segment
    
    * in admin home show only enabled widgets
    
    * refs #10295 use getMockBuilder instead of deprecated getMock
    
    * fix some ui tests
    
    * fix various bugs
    
    * fix more tests
    
    * fix ui tests
    
    * add a space between loading image and loading message
    
    * fix docs so they appear on developer.piwik.org
    
    * improved documentation
    
    * introduce new Widget::renderTemplate method for consistency with controllers
    
    * remove no longer needed files
    
    * testing system fonts
    
    * fix strong was not really bold
    
    * more useful system summary
    
    * remove ubuntu font
    
    * fix most tests and removed most em elements
    
    * fix tests
    
    * fix headline was very thin
    
    * update submodule
    
    * update submodules
    
    * update submodule
    
    * fix failing ui tests
    
    * update submodules
    0c9c30b7
    Historique
    Better UI for Piwik 3, more responsive, faster, lots of other fixes (#10397)
    Thomas Steur a rédigé
    * improved ui and responsiveness
    
    * improve rss widget
    
    * commit changes for ui again, got lost after the last commit
    
    * fix more tests
    
    * restoring files
    
    * fix fonts
    
    * fix more tests
    
    * more test fixes
    
    * fix some system tests
    
    * fix tests
    
    * fix system and ui tests
    
    * fix updater tests
    
    * make a page as loaded once the callback is called
    
    * enable verbose
    
    * more verbose output
    
    * enable phantomjs debug flag
    
    * debug should be a phantomjs option
    
    * trying to fix installation tests
    
    * fixes #10173 to not compile css files as less
    
    * trying to minimize js/css requests to hopefully prevent random ui test fails
    
    * disable verbose mode
    
    * fix updater and installation
    
    * lots of bugfixes and ui tweaks
    
    * fix reset dashboard
    
    * various bugfixes
    
    * fix integration tests
    
    * fix text color
    
    * hoping to fix installation tests this way
    
    * cache css/js resources for an hour, should speed up tests and prevent some random issues
    
    * we need to avoid installing plugins multiple times at the same time when requesting resources
    
    * finally getting the colors right again
    
    * fix most tests, more tests for theme
    
    * use an h2 element for titles for better accessibility
    
    * fix headline color
    
    * use actual theme text color (piwik-black)
    
    * fix small font size was applied on all p elements
    
    * fix tests
    
    * now improving all the datatables
    
    * trying to ignore images for visitor log
    
    * Revert "trying to ignore images for visitor log"
    
    This reverts commit ad1ff7267aae14ad905bef130e956c8593c4fb22.
    
    * fix tests
    
    * fix we had always ignored a max label width
    
    * trying to fix file permissions
    
    * fix more file permissions
    
    * Improved plugins update API (#10028)
    
    * refs #7983 let plugins add or remove fields to websites and better settings api
    
    * * Hide CorePluginsAdmin API methods
    * More documentation
    * Added some more tests
    
    * improved updates API for plugins
    
    * better error code as duplicate column cannot really happen when not actually renaming a colum
    
    Conflicts:
    	core/Updates/3.0.0-b1.php
    	plugins/CoreUpdater/Commands/Update/CliUpdateObserver.php
    
    * fix DB field piwik_log_visit.location_provider too small (#10003)
    
    * fixes #9564 fix DB field piwik_log_visit.location_provider too small
    
    * use new plugins updater API
    
    * DB field piwik_log_visit.visit_total_actions too small (#10002)
    
    * fixes #9565 DB field piwik_log_visit.visit_total_actions too small
    
    * change type of some db columns that are too small
    
    * fix tests (#10040)
    Conflicts:
    	plugins/CoreAdminHome/Menu.php
    	plugins/Goals/Menu.php
    	plugins/MobileMessaging/Menu.php
    	plugins/SitesManager/Menu.php
    	plugins/UsersManager/Menu.php
    	tests/PHPUnit/System/expected/test_apiGetReportMetadata__API.getWidgetMetadata.xml
    
    * fix more file permissions
    
    * repair more file permissions
    
    * repair more file permissions
    
    * trying to make ui tests work again, the table was missing
    
    * fix some encoding issues
    
    * cross browser fixes and usability improvement
    
    * move back the config icon, need to find a better solution later
    
    * more cross browser fixes
    
    * bugfixes
    
    * fix ui tests
    
    * fix encoding issue
    
    * fix various issues with the ui tests when a test gets aborted
    
    * also skip this visitor log test when aborted
    
    * there were 3 css files that were loaded separately, merge them instead into one css
    
    * forgot to add the actual manifest
    
    * do not add manifest if custom logo is specified
    
    * load font css files first as it was before merging them into big css
    
    * fix link icon was not aligned anymore
    
    * minor fixes
    
    * setting it back to 4px
    
    * in popovers the font variable was always ignored and a different font loaded
    
    * forgot to update screenshots
    
    * fix remaining tests
    
    * this should fix an update error
    
    * added 3 new widgets system check, system summary and plugin updates
    
    * tweak new widgets content
    
    * no page reload when changing date or segment
    
    * in admin home show only enabled widgets
    
    * refs #10295 use getMockBuilder instead of deprecated getMock
    
    * fix some ui tests
    
    * fix various bugs
    
    * fix more tests
    
    * fix ui tests
    
    * add a space between loading image and loading message
    
    * fix docs so they appear on developer.piwik.org
    
    * improved documentation
    
    * introduce new Widget::renderTemplate method for consistency with controllers
    
    * remove no longer needed files
    
    * testing system fonts
    
    * fix strong was not really bold
    
    * more useful system summary
    
    * remove ubuntu font
    
    * fix most tests and removed most em elements
    
    * fix tests
    
    * fix headline was very thin
    
    * update submodule
    
    * update submodules
    
    * update submodule
    
    * fix failing ui tests
    
    * update submodules
Controller.php 13,96 Kio
<?php
/**
 * Piwik - free/libre analytics platform
 *
 * @link http://piwik.org
 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
 *
 */
namespace Piwik\Plugins\UserCountry;

use Exception;
use Piwik\Common;
use Piwik\DataTable\Renderer\Json;
use Piwik\Http;
use Piwik\IP;
use Piwik\Piwik;
use Piwik\Plugins\UserCountry\LocationProvider\GeoIp\ServerBased;
use Piwik\Plugins\UserCountry\LocationProvider\GeoIp;
use Piwik\Plugins\UserCountry\LocationProvider;
use Piwik\Plugins\UserCountry\LocationProvider\DefaultProvider;
use Piwik\Plugins\UserCountry\LocationProvider\GeoIp\Pecl;
use Piwik\View;

/**
 *
 */
class Controller extends \Piwik\Plugin\ControllerAdmin
{
    public function getDistinctCountries()
    {
        $view = new View('@UserCountry/getDistinctCountries');

        $view->urlSparklineCountries = $this->getUrlSparkline('getLastDistinctCountriesGraph');
        $view->numberDistinctCountries = $this->getNumberOfDistinctCountries(true);

        return $view->render();
    }

    public function adminIndex()
    {
        $this->dieIfGeolocationAdminIsDisabled();
        Piwik::checkUserHasSuperUserAccess();
        $view = new View('@UserCountry/adminIndex');

        $allProviderInfo = LocationProvider::getAllProviderInfo($newline = '<br/>', $includeExtra = true);
        $view->locationProviders = $allProviderInfo;
        $view->currentProviderId = LocationProvider::getCurrentProviderId();
        $view->thisIP = IP::getIpFromHeader();
        $geoIPDatabasesInstalled = GeoIp::isDatabaseInstalled();
        $view->geoIPDatabasesInstalled = $geoIPDatabasesInstalled;
        $view->updatePeriodOptions = $this->getPeriodUpdateOptions();

        // check if there is a working provider (that isn't the default one)
        $isThereWorkingProvider = false;
        foreach ($allProviderInfo as $id => $provider) {
            if ($id != DefaultProvider::ID
                && $provider['status'] == LocationProvider::INSTALLED
            ) {
                $isThereWorkingProvider = true;
                break;
            }
        }
        $view->isThereWorkingProvider = $isThereWorkingProvider;

        // if using either the Apache or PECL module, they are working and there are no databases
        // in misc, then the databases are located outside of Piwik, so we cannot update them
        $view->showGeoIPUpdateSection = true;
        $currentProviderId = LocationProvider::getCurrentProviderId();
        if (!$geoIPDatabasesInstalled
            && ($currentProviderId == ServerBased::ID
                || $currentProviderId == Pecl::ID)
            && $allProviderInfo[$currentProviderId]['status'] == LocationProvider::INSTALLED
        ) {
            $view->showGeoIPUpdateSection = false;
        }

        $this->setUpdaterManageVars($view);
        $this->setBasicVariablesView($view);
        $this->setBasicVariablesAdminView($view);

        return $view->render();
    }

    /**
     * Starts or continues download of GeoLiteCity.dat.
     *
     * To avoid a server/PHP timeout & to show progress of the download to the user, we
     * use the HTTP Range header to download one chunk of the file at a time. After each
     * chunk, it is the browser's responsibility to call the method again to continue the download.
     *
     * Input:
     *   'continue' query param - if set to 1, will assume we are currently downloading & use
     *                            Range: HTTP header to get another chunk of the file.
     *
     * Output (in JSON):
     *   'current_size' - Current size of the partially downloaded file on disk.
     *   'expected_file_size' - The expected finished file size as returned by the HTTP server.
     *   'next_screen' - When the download finishes, this is the next screen that should be shown.
     *   'error' - When an error occurs, the message is returned in this property.
     */
    public function downloadFreeGeoIPDB()
    {
        $this->dieIfGeolocationAdminIsDisabled();
        Piwik::checkUserHasSuperUserAccess();
        if ($_SERVER["REQUEST_METHOD"] == "POST") {
            $this->checkTokenInUrl();
            Json::sendHeaderJSON();
            $outputPath = GeoIp::getPathForGeoIpDatabase('GeoIPCity.dat') . '.gz';
            try {
                $result = Http::downloadChunk(
                    $url = GeoIp::GEO_LITE_URL,
                    $outputPath,
                    $continue = Common::getRequestVar('continue', true, 'int')
                );

                // if the file is done
                if ($result['current_size'] >= $result['expected_file_size']) {
                    GeoIPAutoUpdater::unzipDownloadedFile($outputPath, $unlink = true);

                    // setup the auto updater
                    GeoIPAutoUpdater::setUpdaterOptions(array(
                                                             'loc_db' => GeoIp::GEO_LITE_URL,
                                                             'period' => GeoIPAutoUpdater::SCHEDULE_PERIOD_MONTHLY,
                                                        ));

                    // make sure to echo out the geoip updater management screen
                    $result['next_screen'] = $this->getGeoIpUpdaterManageScreen();
                }

                return json_encode($result);
            } catch (Exception $ex) {
                return json_encode(array('error' => $ex->getMessage()));
            }
        }
    }

    /**
     * Renders and returns the HTML that manages the GeoIP auto-updater.
     *
     * @return string
     */
    private function getGeoIpUpdaterManageScreen()
    {
        $view = new View('@UserCountry/getGeoIpUpdaterManageScreen');

        $view->updatePeriodOptions = $this->getPeriodUpdateOptions();
        $view->geoIPDatabasesInstalled = true;
        $this->setUpdaterManageVars($view);
        return $view->render();
    }

    private function getPeriodUpdateOptions()
    {
        return array(
            'month' => Piwik::translate('Intl_PeriodMonth'),
            'week' => Piwik::translate('Intl_PeriodWeek')
        );
    }

    /**
     * Sets some variables needed by the _updaterManage.twig template.
     *
     * @param View $view
     */
    private function setUpdaterManageVars($view)
    {
        $urls = GeoIPAutoUpdater::getConfiguredUrls();

        $view->geoIPLocUrl = $urls['loc'];
        $view->geoIPIspUrl = $urls['isp'];
        $view->geoIPOrgUrl = $urls['org'];
        $view->geoIPUpdatePeriod = GeoIPAutoUpdater::getSchedulePeriod();

        $view->geoLiteUrl = GeoIp::GEO_LITE_URL;

        $lastRunTime = GeoIPAutoUpdater::getLastRunTime();
        if ($lastRunTime !== false) {
            $view->lastTimeUpdaterRun = '<strong>' . $lastRunTime->toString() . '</strong>';
        }

        $view->nextRunTime = GeoIPAutoUpdater::getNextRunTime();
    }

    /**
     * Sets the URLs used to download new versions of the installed GeoIP databases.
     *
     * Input (query params):
     *   'loc_db' - URL for a GeoIP location database.
     *   'isp_db' - URL for a GeoIP ISP database (optional).
     *   'org_db' - URL for a GeoIP Org database (optional).
     *   'period' - 'weekly' or 'monthly'. Determines how often update is run.
     *
     * Output (json):
     *   'error' - if an error occurs its message is set as the resulting JSON object's
     *             'error' property.
     */
    public function updateGeoIPLinks()
    {
        $this->dieIfGeolocationAdminIsDisabled();
        Piwik::checkUserHasSuperUserAccess();
        if ($_SERVER["REQUEST_METHOD"] == "POST") {
            Json::sendHeaderJSON();
            try {
                $this->checkTokenInUrl();

                GeoIPAutoUpdater::setUpdaterOptionsFromUrl();

                // if there is a updater URL for a database, but its missing from the misc dir, tell
                // the browser so it can download it next
                $info = $this->getNextMissingDbUrlInfo();
                if ($info !== false) {
                    return json_encode($info);
                } else {
                    $view = new View("@UserCountry/_updaterNextRunTime");
                    $view->nextRunTime = GeoIPAutoUpdater::getNextRunTime();
                    $nextRunTimeHtml = $view->render();
                    return json_encode(array('nextRunTime' => $nextRunTimeHtml));
                }
            } catch (Exception $ex) {
                return json_encode(array('error' => $ex->getMessage()));
            }
        }
    }

    /**
     * Starts or continues a download for a missing GeoIP database. A database is missing if
     * it has an update URL configured, but the actual database is not available in the misc
     * directory.
     *
     * Input:
     *   'url' - The URL to download the database from.
     *   'continue' - 1 if we're continuing a download, 0 if we're starting one.
     *
     * Output:
     *   'error' - If an error occurs this describes the error.
     *   'to_download' - The URL of a missing database that should be downloaded next (if any).
     *   'to_download_label' - The label to use w/ the progress bar that describes what we're
     *                         downloading.
     *   'current_size' - Size of the current file on disk.
     *   'expected_file_size' - Size of the completely downloaded file.
     */
    public function downloadMissingGeoIpDb()
    {
        $this->dieIfGeolocationAdminIsDisabled();
        Piwik::checkUserHasSuperUserAccess();
        if ($_SERVER["REQUEST_METHOD"] == "POST") {
            try {
                $this->checkTokenInUrl();

                Json::sendHeaderJSON();

                // based on the database type (provided by the 'key' query param) determine the
                // url & output file name
                $key = Common::getRequestVar('key', null, 'string');
                $url = GeoIPAutoUpdater::getConfiguredUrl($key);

                $ext = GeoIPAutoUpdater::getGeoIPUrlExtension($url);
                $filename = GeoIp::$dbNames[$key][0] . '.' . $ext;

                if (substr($filename, 0, 15) == 'GeoLiteCity.dat') {
                    $filename = 'GeoIPCity.dat' . substr($filename, 15);
                }
                $outputPath = GeoIp::getPathForGeoIpDatabase($filename);

                // download part of the file
                $result = Http::downloadChunk(
                    $url, $outputPath, Common::getRequestVar('continue', true, 'int'));

                // if the file is done
                if ($result['current_size'] >= $result['expected_file_size']) {
                    GeoIPAutoUpdater::unzipDownloadedFile($outputPath, $unlink = true);

                    $info = $this->getNextMissingDbUrlInfo();
                    if ($info !== false) {
                        return json_encode($info);
                    }
                }

                return json_encode($result);
            } catch (Exception $ex) {
                return json_encode(array('error' => $ex->getMessage()));
            }
        }
    }

    /**
     * Sets the current LocationProvider type.
     *
     * Input:
     *   Requires the 'id' query parameter to be set to the desired LocationProvider's ID.
     *
     * Output:
     *   Nothing.
     */
    public function setCurrentLocationProvider()
    {
        $this->dieIfGeolocationAdminIsDisabled();
        Piwik::checkUserHasSuperUserAccess();
        if ($_SERVER["REQUEST_METHOD"] == "POST") {
            $this->checkTokenInUrl();

            $providerId = Common::getRequestVar('id');
            $provider = LocationProvider::setCurrentProvider($providerId);
            if ($provider === false) {
                throw new Exception("Invalid provider ID: '$providerId'.");
            }
            return 1;
        }
    }

    /**
     * Echo's a pretty formatted location using a specific LocationProvider.
     *
     * Input:
     *   The 'id' query parameter must be set to the ID of the LocationProvider to use.
     *
     * Output:
     *   The pretty formatted location that was obtained. Will be HTML.
     */
    public function getLocationUsingProvider()
    {
        $providerId = Common::getRequestVar('id');
        $provider = LocationProvider::getProviderById($providerId);
        if (empty($provider)) {
            throw new Exception("Invalid provider ID: '$providerId'.");
        }

        $location = $provider->getLocation(array('ip'                => IP::getIpFromHeader(),
                                                 'lang'              => Common::getBrowserLanguage(),
                                                 'disable_fallbacks' => true));
        $location = LocationProvider::prettyFormatLocation(
            $location, $newline = '<br/>', $includeExtra = true);

        return $location;
    }

    public function getNumberOfDistinctCountries()
    {
        return $this->getNumericValue('UserCountry.getNumberOfDistinctCountries');
    }

    public function getLastDistinctCountriesGraph()
    {
        $view = $this->getLastUnitGraph('UserCountry', __FUNCTION__, "UserCountry.getNumberOfDistinctCountries");
        $view->config->columns_to_display = array('UserCountry_distinctCountries');
        return $this->renderView($view);
    }

    /**
     * Gets information for the first missing GeoIP database (if any).
     *
     * @return bool
     */
    private function getNextMissingDbUrlInfo()
    {
        $missingDbs = GeoIPAutoUpdater::getMissingDatabases();
        if (!empty($missingDbs)) {
            $missingDbKey = $missingDbs[0];
            $missingDbName = GeoIp::$dbNames[$missingDbKey][0];
            $url = GeoIPAutoUpdater::getConfiguredUrl($missingDbKey);

            $link = '<a href="' . $url . '">' . $missingDbName . '</a>';

            return array(
                'to_download'       => $missingDbKey,
                'to_download_label' => Piwik::translate('UserCountry_DownloadingDb', $link) . '...',
            );
        }
        return false;
    }

    private function dieIfGeolocationAdminIsDisabled()
    {
        if (!UserCountry::isGeoLocationAdminEnabled()) {
            throw new \Exception('Geo location setting page has been disabled.');
        }
    }
}