Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormattpiwik <matthieu.aubry@gmail.com>2007-08-29 21:28:07 +0400
committermattpiwik <matthieu.aubry@gmail.com>2007-08-29 21:28:07 +0400
commit62ff9b52a06d97bd7edecd9d81bb95d060763800 (patch)
tree8d55bb8503f17707fb0dcf33fd694068da08c90d /modules
parent5819eda4fff1051164234750a694f9885935b1ca (diff)
- Comments
- Controller code / frontController - Login module + deported the auth setup in plugin - Url helper git-svn-id: http://dev.piwik.org/svn/trunk@51 59fd770c-687e-43c8-a1e3-f5a4ff64c105
Diffstat (limited to 'modules')
-rwxr-xr-xmodules/API/Proxy.php10
-rw-r--r--modules/API/Request.php2
-rwxr-xr-xmodules/Access.php97
-rw-r--r--modules/Archive.php17
-rw-r--r--modules/ArchiveProcessing.php10
-rw-r--r--modules/Auth.php36
-rw-r--r--modules/Common.php2
-rwxr-xr-xmodules/Config.php4
-rw-r--r--modules/Controller.php9
-rw-r--r--modules/DataTable.php5
-rw-r--r--modules/Date.php4
-rwxr-xr-xmodules/ErrorHandler.php12
-rw-r--r--modules/ExceptionHandler.php5
-rwxr-xr-xmodules/Log.php5
-rw-r--r--modules/Log/APICall.php13
-rw-r--r--modules/Log/Error.php12
-rw-r--r--modules/Log/Exception.php12
-rw-r--r--modules/Log/Message.php13
-rw-r--r--modules/Log/Null.php16
-rw-r--r--modules/LogStats.php2
-rw-r--r--modules/LogStats/Action.php130
-rw-r--r--modules/LogStats/Config.php6
-rw-r--r--modules/LogStats/Cookie.php63
-rw-r--r--modules/LogStats/Db.php53
-rw-r--r--modules/LogStats/Generator.php37
-rw-r--r--modules/LogStats/Visit.php74
-rw-r--r--modules/Period.php16
-rwxr-xr-xmodules/Piwik.php58
-rw-r--r--modules/Plugin.php2
-rw-r--r--modules/PluginsManager.php3
-rw-r--r--modules/Site.php5
-rwxr-xr-xmodules/SitesManager.php5
-rw-r--r--modules/TablePartitioning.php5
-rw-r--r--modules/Timer.php4
-rw-r--r--modules/Translate.php4
-rw-r--r--modules/Url.php68
-rwxr-xr-xmodules/UsersManager.php6
37 files changed, 642 insertions, 183 deletions
diff --git a/modules/API/Proxy.php b/modules/API/Proxy.php
index 35d2b6e0e8..5107c82e25 100755
--- a/modules/API/Proxy.php
+++ b/modules/API/Proxy.php
@@ -258,6 +258,8 @@ class Piwik_API_Proxy
try {
assert(!is_null(self::$classCalled));
+ $this->registerClass(self::$classCalled);
+
$className = $this->getClassNameFromModule(self::$classCalled);
// instanciate the object
@@ -286,12 +288,8 @@ class Piwik_API_Proxy
$returnedValue
);
}
- catch( Exception $e)
- {
- //TODO replace with nice error message
- Piwik::log("<br>\n Error during API call {$className}.{$methodName}...
- <br>\n => ". $e->getMessage());
-
+ catch( Piwik_Access_NoAccessException $e) {
+ throw $e;
}
self::$classCalled = null;
diff --git a/modules/API/Request.php b/modules/API/Request.php
index 58204ac631..164a793905 100644
--- a/modules/API/Request.php
+++ b/modules/API/Request.php
@@ -131,7 +131,7 @@ class Piwik_API_Request
}
} catch(Exception $e ) {
- $toReturn = 'XML ERROR TEMPLATE TODO';
+ $toReturn = 'XML ERROR TEMPLATE TODO', $e;
}
return $toReturn;
}
diff --git a/modules/Access.php b/modules/Access.php
index 28c44103a9..ffa3284824 100755
--- a/modules/Access.php
+++ b/modules/Access.php
@@ -1,4 +1,25 @@
<?php
+/**
+ * Class to handle User Access.
+ * In Piwik there are mainly 4 access levels
+ * - no access
+ * - VIEW access
+ * - ADMIN access
+ * - Super admin access
+ *
+ * An access level is on a per website basis.
+ * A given user has a given access level for a given website.
+ * For example:
+ * User Noemie has
+ * - VIEW access on the website 1,
+ * - ADMIN on the website 2 and 4, and
+ * - NO access on the website 3 and 5
+ *
+ * There is only one Super User ; he has ADMIN access to all the websites
+ * and he only can change the main configuration settings.
+ *
+ * @package Piwik
+ */
require_once 'SitesManager.php';
class Piwik_Access
{
@@ -11,16 +32,32 @@ class Piwik_Access
static private $availableAccess = array('noaccess', 'view', 'admin', 'superuser');
+ /**
+ * Returns the list of the existing Access level.
+ * Useful when a given API method requests a given acccess Level.
+ * We first check that the required access level exists.
+ */
static public function getListAccess()
{
return self::$availableAccess;
}
+ /**
+ * @param Piwik_Auth The authentification object
+ */
public function __construct( $auth )
{
$this->auth = $auth;
}
+ /**
+ * Load the access levels for the current user.
+ *
+ * First call the authentication method to try to log the user in the system.
+ * If the user credentials are not correct we don't load anything.
+ * If the login/password is correct the user is either the SuperUser or a normal user.
+ * We load the access levels for this user for all the websites.
+ */
public function loadAccess()
{
$accessByIdsite = array();
@@ -64,11 +101,22 @@ class Piwik_Access
$this->idsitesByAccess = $idsitesByAccess;
}
+ /**
+ * Returns the user login
+ * @return string
+ */
public function getIdentity()
{
return $this->identity;
}
+ /**
+ * Returns an array of ID sites for which the user has at least a VIEW access.
+ * Which means VIEW or ADMIN or SUPERUSER.
+ *
+ * @return array Example if the user is ADMIN for 4
+ * and has VIEW access for 1 and 7, it returns array(1, 4, 7);
+ */
public function getSitesIdWithAtLeastViewAccess()
{
return array_unique(array_merge(
@@ -77,6 +125,13 @@ class Piwik_Access
$this->idsitesByAccess['superuser']));
}
+
+ /**
+ * Returns an array of ID sites for which the user has an ADMIN access.
+ *
+ * @return array Example if the user is ADMIN for 4 and 8
+ * and has VIEW access for 1 and 7, it returns array(4, 8);
+ */
public function getSitesIdWithAdminAccess()
{
return array_unique(array_merge(
@@ -84,27 +139,50 @@ class Piwik_Access
$this->idsitesByAccess['superuser']));
}
+
+ /**
+ * Returns an array of ID sites for which the user has a VIEW access only.
+ *
+ * @return array Example if the user is ADMIN for 4
+ * and has VIEW access for 1 and 7, it returns array(1, 7);
+ * @see getSitesIdWithAtLeastViewAccess()
+ */
public function getSitesIdWithViewAccess()
{
return $this->idsitesByAccess['view'];
}
-
+
+ /**
+ * Throws an exception if the user is not the SuperUser
+ * @throws Exception
+ */
public function checkUserIsSuperUser()
{
if($this->isSuperUser === false)
{
- throw new Exception("You can't access this resource as it requires a 'superuser' access.");
+ throw new Piwik_Access_NoAccessException("You can't access this resource as it requires a 'superuser' access.");
}
}
+ /**
+ * If the user doesn't have an ADMIN access for at least one website, throws an exception
+ * @throws Exception
+ */
public function checkUserHasSomeAdminAccess()
{
$idSitesAccessible = $this->getSitesIdWithAdminAccess();
if(count($idSitesAccessible) == 0)
{
- throw new Exception("You can't access this resource as it requires an 'admin' access for at least one website.");
+ throw new Piwik_Access_NoAccessException("You can't access this resource as it requires an 'admin' access for at least one website.");
}
}
+
+ /**
+ * This method checks that the user has ADMIN access for the given list of websites.
+ * If the user doesn't have ADMIN access for at least one website of the list, we throw an exception.
+ * @param int|arrayOfIntegers List of ID sites to check
+ * @throws Exception If for any of the websites the user doesn't have an ADMIN access
+ */
public function checkUserHasAdminAccess( $idSites )
{
if(!is_array($idSites))
@@ -116,11 +194,18 @@ class Piwik_Access
{
if(!in_array($idsite, $idSitesAccessible))
{
- throw new Exception("You can't access this resource as it requires an 'admin' access for the website id = $idsite.");
+ throw new Piwik_Access_NoAccessException("You can't access this resource as it requires an 'admin' access for the website id = $idsite.");
}
}
}
+
+ /**
+ * This method checks that the user has VIEW or ADMIN access for the given list of websites.
+ * If the user doesn't have VIEW or ADMIN access for at least one website of the list, we throw an exception.
+ * @param int|arrayOfIntegers List of ID sites to check
+ * @throws Exception If for any of the websites the user doesn't have an VIEW or ADMIN access
+ */
public function checkUserHasViewAccess( $idSites )
{
if(!is_array($idSites))
@@ -132,9 +217,11 @@ class Piwik_Access
{
if(!in_array($idsite, $idSitesAccessible))
{
- throw new Exception("You can't access this resource as it requires a 'view' access for the website id = $idsite.");
+ throw new Piwik_Access_NoAccessException("You can't access this resource as it requires a 'view' access for the website id = $idsite.");
}
}
}
}
+class Piwik_Access_NoAccessException extends Exception
+{} \ No newline at end of file
diff --git a/modules/Archive.php b/modules/Archive.php
index b4dfcd737c..b527e3ea41 100644
--- a/modules/Archive.php
+++ b/modules/Archive.php
@@ -1,23 +1,11 @@
<?php
/**
* Archiving process
- *
- *
+ *
* Requirements
*
- * + needs powerful and easy date handling => Zend_Date
- * + Needs many date helper functions
- * from a day, gives the week + list of the days in the week
- * from a day, gives the month + list of the days in the month
- * from a day, gives the year + list of the days in the year + list of the months in the year
- * - Contact with DB abstracted from the archive process
- * - Handle multi periods: day, week, month, year
- * - Each period logic is separated into different classes
- * so that we can in the future easily add new weird periods
- * - support for partial archive (today's archive for example, but not limited to today)
*
- * Features:
- * - delete logs once used for days
+ * TODO delete logs once used for days
* it means that we have to keep the useful information for months/week etc.
* check also that the logging process doesn't use the logs we are deleting
*
@@ -36,6 +24,7 @@
* receives data directly from the sql query via a known API
* - The *ArchiveProcessing* saves in the DB *numbers* or *Table* objects
*
+ * @package Piwik
*/
require_once 'Period.php';
diff --git a/modules/ArchiveProcessing.php b/modules/ArchiveProcessing.php
index beac05210d..79a0b21232 100644
--- a/modules/ArchiveProcessing.php
+++ b/modules/ArchiveProcessing.php
@@ -1,5 +1,4 @@
<?php
-
/**
* The ArchiveProcessing module is a module that reads the Piwik logs from the DB and
* compute all the reports, which are then stored in the database.
@@ -13,6 +12,8 @@
* - ts_archived = timestamp when the archive was processed
* - name = the name of the report (ex: uniq_visitors or search_keywords_by_search_engines)
* - value = the actual data
+ *
+ * @package Piwik_ArchiveProcessing
*/
require_once 'TablePartitioning.php';
require_once 'ArchiveProcessing/Record.php';
@@ -32,7 +33,7 @@ abstract class Piwik_ArchiveProcessing
protected $tableArchiveBlob;
protected $maxTimestampArchive;
- // Attributes that can be used by plugins
+ // Attributes that can be accessed by plugins (that is why they are public)
public $idsite = null;
public $period = null;
public $site = null;
@@ -44,7 +45,9 @@ abstract class Piwik_ArchiveProcessing
public $logVisitActionTable;
public $logActionTable;
-
+ /**
+ *
+ */
protected function loadArchiveProperties()
{
$this->idsite = $this->site->getId();
@@ -76,6 +79,7 @@ abstract class Piwik_ArchiveProcessing
{
return $this->tableArchiveNumeric;
}
+
public function getTableArchiveBlobName()
{
return $this->tableArchiveBlob;
diff --git a/modules/Auth.php b/modules/Auth.php
index 49cecc573d..94769e0824 100644
--- a/modules/Auth.php
+++ b/modules/Auth.php
@@ -1,15 +1,8 @@
<?php
-
-class Piwik_Auth_Result extends Zend_Auth_Result
-{
- public function __construct($code, $identity, array $messages = array())
- {
- $this->_code = (int)$code;
- $this->_identity = $identity;
- $this->_messages = $messages;
- }
-}
-
+/**
+ *
+ * @package Piwik
+ */
class Piwik_Auth extends Zend_Auth_Adapter_DbTable
{
const SUCCESS_SUPERUSER_AUTH_CODE = 42;
@@ -25,17 +18,18 @@ class Piwik_Auth extends Zend_Auth_Adapter_DbTable
// we first try if the user is the super user
$login = $this->_identity;
- $password = $this->_credential;
+ $token = $this->_credential;
$rootLogin = Zend_Registry::get('config')->superuser->login;
$rootPassword = Zend_Registry::get('config')->superuser->password;
+ $rootToken = Piwik_UsersManager_API::getTokenAuth($rootLogin,$rootPassword);
if($login == $rootLogin
- && $password == $rootPassword)
+ && $token == $rootToken)
{
return new Piwik_Auth_Result(Piwik_Auth::SUCCESS_SUPERUSER_AUTH_CODE,
$login,
array() // message empty
- );
+ );
}
// if not then we return the result of the database authentification provided by zend
@@ -45,3 +39,17 @@ class Piwik_Auth extends Zend_Auth_Adapter_DbTable
}
+
+/**
+ *
+ * @package Piwik
+ */
+class Piwik_Auth_Result extends Zend_Auth_Result
+{
+ public function __construct($code, $identity, array $messages = array())
+ {
+ $this->_code = (int)$code;
+ $this->_identity = $identity;
+ $this->_messages = $messages;
+ }
+}
diff --git a/modules/Common.php b/modules/Common.php
index d4101569fb..278a1dc878 100644
--- a/modules/Common.php
+++ b/modules/Common.php
@@ -6,6 +6,8 @@
* This is the only external class loaded by the Piwik.php file.
* This class should contain only the functions that are used in
* both the CORE and the piwik.php statistics logging engine.
+ *
+ * @package Piwik
*/
class Piwik_Common
{
diff --git a/modules/Config.php b/modules/Config.php
index ff31e16e56..a228312c78 100755
--- a/modules/Config.php
+++ b/modules/Config.php
@@ -1,4 +1,8 @@
<?php
+/**
+ *
+ * @package Piwik
+ */
require_once "Zend/Config/Ini.php";
require_once "Zend/Registry.php";
class Piwik_Config extends Zend_Config_Ini
diff --git a/modules/Controller.php b/modules/Controller.php
new file mode 100644
index 0000000000..8bf0087eff
--- /dev/null
+++ b/modules/Controller.php
@@ -0,0 +1,9 @@
+<?php
+abstract class Piwik_Controller
+{
+ function getDefaultAction()
+ {
+ return 'index';
+ }
+}
+?>
diff --git a/modules/DataTable.php b/modules/DataTable.php
index c14a6040ed..da835fd200 100644
--- a/modules/DataTable.php
+++ b/modules/DataTable.php
@@ -1,6 +1,7 @@
<?php
/**
*
+ *
* Initial Specification
* ---------------------------------------------------------
* CAREFUL: It may be outdated as I have not reviewed it yet
@@ -106,6 +107,8 @@
* $XMLstring = $xmlOutput->getOutput();
*
*
+ * @package Piwik
+ * @subpackage Piwik_DataTable
*
*/
require_once "DataTable/Renderer.php";
@@ -250,7 +253,7 @@ class Piwik_DataTable
{
if(isset($this->rowsIndexByLabel[$label]))
{
- throw new Exception("The row with the label $label already exist in this DataTable");
+ throw new Exception("The row with the label $label already exists in this DataTable");
}
$this->rowsIndexByLabel[$label] = count($this->rows) - 1;
}
diff --git a/modules/Date.php b/modules/Date.php
index 0eec3c9206..9857c395aa 100644
--- a/modules/Date.php
+++ b/modules/Date.php
@@ -1,4 +1,8 @@
<?php
+/**
+ *
+ * @package Piwik
+ */
Zend_Loader::loadClass('Zend_Date');
class Piwik_Date extends Zend_Date
{
diff --git a/modules/ErrorHandler.php b/modules/ErrorHandler.php
index 76a562da8a..5887e071ff 100755
--- a/modules/ErrorHandler.php
+++ b/modules/ErrorHandler.php
@@ -1,10 +1,14 @@
<?php
+/**
+ *
+ * @package Piwik
+ */
function Piwik_ErrorHandler($errno, $errstr, $errfile, $errline)
{
-// ob_start();
-// debug_print_backtrace();
-// $backtrace = ob_get_contents();
-// ob_end_clean();
+ ob_start();
+ debug_print_backtrace();
+ $backtrace = ob_get_contents();
+ ob_end_clean();
Zend_Registry::get('logger_error')->log($errno, $errstr, $errfile, $errline, $backtrace);
switch($errno)
diff --git a/modules/ExceptionHandler.php b/modules/ExceptionHandler.php
index 9446ef02a0..5d17925841 100644
--- a/modules/ExceptionHandler.php
+++ b/modules/ExceptionHandler.php
@@ -1,5 +1,8 @@
<?php
-
+/**
+ *
+ * @package Piwik
+ */
function Piwik_ExceptionHandler(Exception $exception)
{
try {
diff --git a/modules/Log.php b/modules/Log.php
index b1b56363ac..7e66a45112 100755
--- a/modules/Log.php
+++ b/modules/Log.php
@@ -1,4 +1,9 @@
<?php
+/**
+ *
+ *
+ * @package Piwik_Log
+ */
Zend_Loader::loadClass('Zend_Log');
Zend_Loader::loadClass('Zend_Log_Formatter_Interface');
Zend_Loader::loadClass('Zend_Log_Writer_Stream');
diff --git a/modules/Log/APICall.php b/modules/Log/APICall.php
index 72574620d3..519e328d02 100644
--- a/modules/Log/APICall.php
+++ b/modules/Log/APICall.php
@@ -1,5 +1,10 @@
<?php
-
+/**
+ * Class used to log all the API Calls information (class / method / parameters / returned value / time spent)
+ *
+ * @package Piwik_Log
+ * @subpackage Piwik_Log_APICall
+ */
class Piwik_Log_APICall extends Piwik_Log
{
const ID = 'logger_api_call';
@@ -35,6 +40,12 @@ class Piwik_Log_APICall extends Piwik_Log
}
}
+/**
+ * Class used to format the API Call log on the screen.
+ *
+ * @package Piwik_Log
+ * @subpackage Piwik_Log_APICall
+ */
class Piwik_Log_Formatter_APICall_ScreenFormatter implements Zend_Log_Formatter_Interface
{
/**
diff --git a/modules/Log/Error.php b/modules/Log/Error.php
index dfd3558937..015695c3b2 100644
--- a/modules/Log/Error.php
+++ b/modules/Log/Error.php
@@ -1,5 +1,11 @@
<?php
+/**
+ * Class used to log an error event.
+ *
+ * @package Piwik_Log
+ * @subpackage Piwik_Log_Error
+ */
class Piwik_Log_Error extends Piwik_Log
{
const ID = 'logger_error';
@@ -33,6 +39,12 @@ class Piwik_Log_Error extends Piwik_Log
+/**
+ * Format an error event to be displayed on the screen.
+ *
+ * @package Piwik_Log
+ * @subpackage Piwik_Log_Error
+ */
class Piwik_Log_Formatter_Error_ScreenFormatter implements Zend_Log_Formatter_Interface
{
/**
diff --git a/modules/Log/Exception.php b/modules/Log/Exception.php
index 189fe55407..59a4ec7811 100644
--- a/modules/Log/Exception.php
+++ b/modules/Log/Exception.php
@@ -1,5 +1,11 @@
<?php
+/**
+ * Class used to log an exception event.
+ *
+ * @package Piwik_Log
+ * @subpackage Piwik_Log_Exception
+ */
class Piwik_Log_Exception extends Piwik_Log
{
const ID = 'logger_exception';
@@ -33,6 +39,12 @@ class Piwik_Log_Exception extends Piwik_Log
}
+/**
+ * Format an exception event to be displayed on the screen.
+ *
+ * @package Piwik_Log
+ * @subpackage Piwik_Log_Exception
+ */
class Piwik_Log_Formatter_Exception_ScreenFormatter implements Zend_Log_Formatter_Interface
{
/**
diff --git a/modules/Log/Message.php b/modules/Log/Message.php
index e9890ada59..78b84196fb 100644
--- a/modules/Log/Message.php
+++ b/modules/Log/Message.php
@@ -1,5 +1,11 @@
<?php
+/**
+ * Class used to log a standard message event.
+ *
+ * @package Piwik_Log
+ * @subpackage Piwik_Log_Message
+ */
class Piwik_Log_Message extends Piwik_Log
{
const ID = 'logger_message';
@@ -28,6 +34,13 @@ class Piwik_Log_Message extends Piwik_Log
}
+/**
+ * Format a standard message event to be displayed on the screen.
+ * The message can be a PHP array or a string.
+ *
+ * @package Piwik_Log
+ * @subpackage Piwik_Log_Message
+ */
class Piwik_Log_Formatter_Message_ScreenFormatter implements Zend_Log_Formatter_Interface
{
/**
diff --git a/modules/Log/Null.php b/modules/Log/Null.php
deleted file mode 100644
index 0f9e628f32..0000000000
--- a/modules/Log/Null.php
+++ /dev/null
@@ -1,16 +0,0 @@
-<?php
-
-
-class Piwik_Log_Null extends Zend_Log
-{
- public function __construct()
- {
- }
-
- public function log($message, $priority = Zend_Log::INFO )
- {
- parent::log($message, $priority);
- }
-}
-
-
diff --git a/modules/LogStats.php b/modules/LogStats.php
index d603366f08..7b0e80c837 100644
--- a/modules/LogStats.php
+++ b/modules/LogStats.php
@@ -28,6 +28,8 @@
* We could also imagine a batch system that would read a log file every 5min,
* and which prepares the file containg the rows to insert, then we load DATA INFILE
*
+ *
+ * @package Piwik_LogStats
*/
/**
diff --git a/modules/LogStats/Action.php b/modules/LogStats/Action.php
index 7c10d8abc5..79ac0fedb6 100644
--- a/modules/LogStats/Action.php
+++ b/modules/LogStats/Action.php
@@ -1,68 +1,83 @@
<?php
+/**
+ * Handles an action by the visitor.
+ * A request to the piwik.php script is associated with one Action.
+ * This class is used to build the Action Name (which can be built from the URL,
+ * or can be directly specified in the JS code, etc.).
+ * It also saves the Action when necessary in the DB.
+ *
+ *
+ * About the Action concept
+ * ------------------------------------
+ * - An action is defined by a name.
+ * - The name can be specified in the JS Code in the variable 'action_name'
+ * - Handling UTF8 in the action name
+ * PLUGIN_IDEA - An action is associated to URLs and link to the URL from the interface
+ * PLUGIN_IDEA - An action hit by a visitor is associated to the HTML title of the page that triggered the action
+ *
+ * + If the name is not specified, we use the URL(path+query) to build a default name.
+ * For example for "http://piwik.org/test/my_page/test.html"
+ * the name would be "test/my_page/test.html"
+ *
+ * We make sure it is clean and displayable.
+ * If the name is empty we set it to a default name.
+ *
+ * TODO UTF8 handling to test
+ *
+ * Specifications
+ *
+ * - Download tracking
+ *
+ * * MANUAL Download tracking
+ * download = http://piwik.org/hellokity.zip
+ * (name = dir1/file alias name)
+ *
+ * * AUTOMATIC Download tracking for a known list of file extensions.
+ * Make a hit to the piwik.php with the parameter:
+ * download = http://piwik.org/hellokity.zip
+ *
+ * When 'name' is not specified,
+ * if AUTOMATIC and if anchor not empty => name = link title anchor
+ * else name = path+query of the URL
+ * Ex: myfiles/beta.zip
+ *
+ * - External link tracking
+ *
+ * * MANUAL External link tracking
+ * outlink = http://amazon.org/test
+ * (name = the big partners / amazon)
+ *
+ * * AUTOMATIC External link tracking
+ * When a link is not detected as being part of the same website
+ * AND when the url extension is not detected as being a file download
+ * outlink = http://amazon.org/test
+ *
+ * When 'name' is not specified,
+ * if AUTOMATIC and if anchor not empty => name = link title anchor
+ * else name = URL
+ * Ex: http://amazon.org/test
+ *
+ *
+ * @package Piwik_LogStats
+ */
class Piwik_LogStats_Action
{
-
- /*
- * About the Action concept:
- *
- * - An action is defined by a name.
- * - The name can be specified in the JS Code in the variable 'action_name'
- * - Handling UTF8 in the action name
- * PLUGIN_IDEA - An action is associated to URLs and link to the URL from the interface
- * PLUGIN_IDEA - An action hit by a visitor is associated to the HTML title of the page that triggered the action
- *
- * + If the name is not specified, we use the URL(path+query) to build a default name.
- * For example for "http://piwik.org/test/my_page/test.html"
- * the name would be "test/my_page/test.html"
- *
- * We make sure it is clean and displayable.
- * If the name is empty we set it to a default name.
- *
- * TODO UTF8 handling to test
- *
- * Specifications
- *
- * - Download tracking
- *
- * * MANUAL Download tracking
- * download = http://piwik.org/hellokity.zip
- * (name = dir1/file alias name)
- *
- * * AUTOMATIC Download tracking for a known list of file extensions.
- * Make a hit to the piwik.php with the parameter:
- * download = http://piwik.org/hellokity.zip
- *
- * When 'name' is not specified,
- * if AUTOMATIC and if anchor not empty => name = link title anchor
- * else name = path+query of the URL
- * Ex: myfiles/beta.zip
- *
- * - External link tracking
- *
- * * MANUAL External link tracking
- * outlink = http://amazon.org/test
- * (name = the big partners / amazon)
- *
- * * AUTOMATIC External link tracking
- * When a link is not detected as being part of the same website
- * AND when the url extension is not detected as being a file download
- * outlink = http://amazon.org/test
- *
- * When 'name' is not specified,
- * if AUTOMATIC and if anchor not empty => name = link title anchor
- * else name = URL
- * Ex: http://amazon.org/test
- */
private $actionName;
private $url;
private $defaultActionName;
private $nameDownloadOutlink;
+ /**
+ * 3 types of action, Standard action / Download / Outlink click
+ */
const TYPE_ACTION = 1;
const TYPE_DOWNLOAD = 3;
const TYPE_OUTLINK = 2;
+ /**
+ * @param Piwik_LogStats_Db object
+ */
function __construct( $db )
{
$this->actionName = Piwik_Common::getRequestVar( 'action_name', '', 'string');
@@ -81,6 +96,10 @@ class Piwik_LogStats_Action
$this->defaultActionName = Piwik_LogStats_Config::getInstance()->LogStats['default_action_name'];
}
+ /**
+ * Generate the name of the action from the URL or the specified name.
+ * See the class description for more information.
+ */
private function generateInfo()
{
if(!empty($this->downloadUrl))
@@ -170,7 +189,7 @@ class Piwik_LogStats_Action
* The methods takes care of creating a new record in the action table if the existing
* action name doesn't exist yet.
*
- * @return int Id action
+ * @return int Id action that is associated to this action name in the Actions table lookup
*/
function getActionId()
{
@@ -209,6 +228,11 @@ class Piwik_LogStats_Action
/**
* Records in the DB the association between the visit and this action.
+ *
+ * @param int idVisit is the ID of the current visit in the DB table log_visit
+ * @param int idRefererAction is the ID of the last action done by the current visit.
+ * @param int timeSpentRefererAction is the number of seconds since the last action was done.
+ * It is directly related to idRefererAction.
*/
public function record( $idVisit, $idRefererAction, $timeSpentRefererAction)
{
diff --git a/modules/LogStats/Config.php b/modules/LogStats/Config.php
index 1a25ef22d3..a09d17ab42 100644
--- a/modules/LogStats/Config.php
+++ b/modules/LogStats/Config.php
@@ -2,6 +2,12 @@
/**
* Simple class to access the configuration file
+ *
+ * This is essentially a very simple version of Zend_Config that we wrote
+ * because of performance concerns.
+ * The LogStats module can't afford a dependency with the Zend_Framework.
+ *
+ * @package Piwik_LogStats
*/
class Piwik_LogStats_Config
{
diff --git a/modules/LogStats/Cookie.php b/modules/LogStats/Cookie.php
index 0b095a4c4e..ff479442f2 100644
--- a/modules/LogStats/Cookie.php
+++ b/modules/LogStats/Cookie.php
@@ -9,6 +9,8 @@
* - create a new cookie, set values, expiration date, etc. and save it
*
* The cookie content is saved in an optimized way.
+ *
+ * @package Piwik_LogStats
*/
class Piwik_LogStats_Cookie
{
@@ -27,8 +29,18 @@ class Piwik_LogStats_Cookie
*/
protected $value = array();
+ /**
+ * The character used to separate the tuple name=value in the cookie
+ */
const VALUE_SEPARATOR = ':';
+ /**
+ * Instanciate a new Cookie object and tries to load the cookie content if the cookie
+ * exists already.
+ *
+ * @param string cookie Name
+ * @param int The timestamp after which the cookie will expire, eg time() + 86400
+ */
public function __construct( $cookieName, $expire = null)
{
$this->name = $cookieName;
@@ -46,18 +58,28 @@ class Piwik_LogStats_Cookie
}
}
+ /**
+ * Returns true if the visitor already has the cookie.
+ * @return bool
+ */
public function isCookieFound()
{
return isset($_COOKIE[$this->name]);
}
+ /**
+ * Returns the default expiry time, 10 years
+ * @return int Timestamp in 10 years
+ */
protected function getDefaultExpire()
{
return time() + 86400*365*10;
}
/**
- * taken from http://usphp.com/manual/en/function.setcookie.php
+ * We don't use the setcookie function because it is buggy for some PHP versions.
+ *
+ * Taken from http://usphp.com/manual/en/function.setcookie.php
* TODO setCookie: use the other parameters of the function
*/
protected function setCookie($Name, $Value, $Expires, $Path = '', $Domain = '', $Secure = false, $HTTPOnly = false)
@@ -84,17 +106,28 @@ class Piwik_LogStats_Cookie
header($header, false);
}
+ /**
+ * We set the privacy policy header
+ */
protected function setP3PHeader()
{
header("P3P: CP='OTI DSP COR NID STP UNI OTPa OUR'");
}
+ /**
+ * Delete the cookie
+ */
public function deleteCookie()
{
$this->setP3PHeader();
setcookie($this->name, false, time() - 86400);
}
+ /**
+ * Saves the cookie (set the Cookie header).
+ * You have to call this method before sending any text to the browser or you would get the
+ * "Header already sent" error.
+ */
public function save()
{
$this->setP3PHeader();
@@ -102,7 +135,10 @@ class Piwik_LogStats_Cookie
}
/**
- * Load the cookie content into a php array
+ * Load the cookie content into a php array.
+ * Parses the cookie string to extract the different variables.
+ * Unserialize the array when necessary.
+ * Decode the non numeric values that were base64 encoded.
*/
protected function loadContentFromCookie()
{
@@ -135,10 +171,11 @@ class Piwik_LogStats_Cookie
}
/**
- * Returns the string to save in the cookie frpm the $this->value array of values
- *
+ * Returns the string to save in the cookie from the $this->value array of values.
+ * It goes through the array and generate the cookie content string.
+ * @return string Cookie string
*/
- public function generateContentString()
+ protected function generateContentString()
{
$cookieStr = '';
foreach($this->value as $name=>$value)
@@ -163,6 +200,7 @@ class Piwik_LogStats_Cookie
* If the value is an array, it will be saved as a serialized and base64 encoded
* string which is not very good in terms of bytes usage.
* You should save arrays only when you are sure about their maximum data size.
+ * A cookie has to stay small and its size shouldn't increase over time!
*
* @param string Name of the value to save; the name will be used to retrieve this value
* @param string|array|numeric Value to save
@@ -186,6 +224,11 @@ class Piwik_LogStats_Cookie
return isset($this->value[$name]) ? self::escapeValue($this->value[$name]) : false;
}
+ /**
+ * Returns an easy to read cookie dump
+ *
+ * @return string The cookie dump
+ */
public function __toString()
{
$str = "<-- Content of the cookie '{$this->name}' <br>\n";
@@ -197,13 +240,19 @@ class Piwik_LogStats_Cookie
return $str;
}
+ /**
+ * Escape values from the cookie before sending them back to the client
+ * (when using the get() method).
+ *
+ * @return mixed The value once cleaned.
+ */
static protected function escapeValue( $value )
{
return Piwik_Common::sanitizeInputValues($value);
}
}
-//
-//
+
+
//$c = new Piwik_LogStats_Cookie( 'piwik_logstats', 86400);
//echo $c;
//$c->set(1,1);
diff --git a/modules/LogStats/Db.php b/modules/LogStats/Db.php
index 6cd9e70287..ed4309f098 100644
--- a/modules/LogStats/Db.php
+++ b/modules/LogStats/Db.php
@@ -1,18 +1,27 @@
<?php
/**
- * Simple database PDO wrapper
+ * Simple database PDO wrapper.
+ * We can't afford to have a dependency with the Zend_Db module in the LogStats module.
*
+ * TODO write the mysqli wrapper
+ *
+ * @package Piwik_LogStats
*/
+
class Piwik_LogStats_Db
{
private $connection;
private $username;
private $password;
+
//TODO test that in production is false
static private $profiling = false;
protected $queriesProfiling;
+ /**
+ * Builds the DB object
+ */
public function __construct( $host, $username, $password, $dbname)
{
$this->dsn = "mysql:dbname=$dbname;host=$host";
@@ -20,16 +29,28 @@ class Piwik_LogStats_Db
$this->password = $password;
}
+ /**
+ * Enables the profiling.
+ * For each query, saves in the DB the time spent on this query.
+ * Very useful to see the slow query under heavy load.
+ * You can then use Piwik::printLogStatsSQLProfiling();
+ * to display the SQLProfiling report and see which queries take time, etc.
+ */
static public function enableProfiling()
{
self::$profiling = true;
}
+ /**
+ * Disables the profiling logging.
+ */
static public function disableProfiling()
{
self::$profiling = false;
}
-
+ /**
+ * Connects to the DB
+ */
public function connect()
{
try {
@@ -41,6 +62,12 @@ class Piwik_LogStats_Db
}
}
+ /**
+ * Returns the table name prefixed by the table prefix.
+ *
+ * @param string The table name to prefix, ie "log_visit"
+ * @return string The table name prefixed, ie "piwik-production_log_visit"
+ */
public function prefixTable( $suffix )
{
static $prefix;
@@ -50,6 +77,10 @@ class Piwik_LogStats_Db
return $prefix . $suffix;
}
+ /**
+ * Returns an array containing all the rows of a query result.
+ * @see also query()
+ */
public function fetchAll( $query, $parameters )
{
try {
@@ -60,6 +91,10 @@ class Piwik_LogStats_Db
}
}
+ /**
+ * Returns the first row of a query result.
+ * @see query()
+ */
public function fetch( $query, $parameters )
{
try {
@@ -70,6 +105,12 @@ class Piwik_LogStats_Db
}
}
+ /**
+ * Executes a query with bind parameters
+ *
+ * @param string Query
+ * @param array Parameters to bind
+ */
public function query($query, $parameters = array())
{
try {
@@ -98,11 +139,19 @@ class Piwik_LogStats_Db
}
}
+ /**
+ * Returns the last inserted ID in the DB
+ * Wrapper of PDO::lastInsertId()
+ * @return int
+ */
public function lastInsertId()
{
return $this->connection->lastInsertId();
}
+ /**
+ * When destroyed, log the SQL profiling information
+ */
public function __destruct()
{
if(self::$profiling)
diff --git a/modules/LogStats/Generator.php b/modules/LogStats/Generator.php
index 4871c899a9..36090821d0 100644
--- a/modules/LogStats/Generator.php
+++ b/modules/LogStats/Generator.php
@@ -1,10 +1,10 @@
<?php
/**
- * Requirements of the visits generator script
- *
- * Things possible to change
+ * Class used to generate fake visits.
+ * Useful to test performances, general functional testing, etc.
*
+ * Requirements of the visits generator script. It is to edit *
* - url => campaigns
* - newsletter
* - partner
@@ -20,8 +20,9 @@
* - HTML title
*
* Objective:
- * Generate thousands of visits / actions per visitor with random data to test the performance
+ * Generate thousands of visits / actions per visitor
*
+ * @package Piwik_LogStats
*/
class Piwik_LogStats_Generator
@@ -99,33 +100,7 @@ class Piwik_LogStats_Generator
{
if($this->profiling)
{
- function maxSumMsFirst($a,$b)
- {
- return $a['sum_time_ms'] < $b['sum_time_ms'];
- }
-
- $db = Zend_Registry::get('db');
- $all = $db->fetchAll('SELECT *, sum_time_ms / count as avg_time_ms FROM '.Piwik::prefixTable('log_profiling').'' );
- usort($all, 'maxSumMsFirst');
-
-
- $str='<br><br>Query Profiling<br>----------------------<br>';
- foreach($all as $infoQuery)
- {
- $query = $infoQuery['query'];
- $count = $infoQuery['count'];
- $sum_time_ms = $infoQuery['sum_time_ms'];
- $avg_time_ms = round($infoQuery['avg_time_ms'],1);
- $query = str_replace("\t", "", $query);
-
- $str .= "$query <br>
- $count times, <b>$sum_time_ms ms total</b><br>
- $avg_time_ms ms average<br>
- <br>";
- }
-
-
- print($str);
+ Piwik::printLogStatsSQLProfiling();
}
}
diff --git a/modules/LogStats/Visit.php b/modules/LogStats/Visit.php
index 5e3537135b..e98d156fa9 100644
--- a/modules/LogStats/Visit.php
+++ b/modules/LogStats/Visit.php
@@ -1,5 +1,17 @@
<?php
-
+/**
+ * Class used to handle a Visit.
+ * A visit is either NEW or KNOWN.
+ * - If a visit is NEW then we process the visitor information (settings, referers, etc.) and save
+ * a new line in the log_visit table.
+ * - If a visit is KNOWN then we update the visit row in the log_visit table, updating the number of pages
+ * views, time spent, etc.
+ *
+ * Whether a visit is NEW or KNOWN we also save the action in the DB. One request to the piwik.php script
+ * is associated to one action.
+ *
+ * @package Piwik_LogStats
+ */
class Piwik_LogStats_Visit
{
protected $cookieLog = null;
@@ -19,25 +31,42 @@ class Piwik_LogStats_Visit
$this->idsite = $idsite;
}
+ /**
+ * Returns the current date in the "Y-m-d" PHP format
+ * @return string
+ */
protected function getCurrentDate( $format = "Y-m-d")
{
return date($format, $this->getCurrentTimestamp() );
}
+ /**
+ * Returns the current Timestamp
+ * @return int
+ */
protected function getCurrentTimestamp()
{
return time();
}
+ /**
+ * Returns the date in the "Y-m-d H:i:s" PHP format
+ * @return string
+ */
protected function getDatetimeFromTimestamp($timestamp)
{
return date("Y-m-d H:i:s",$timestamp);
}
- // test if the visitor is excluded because of
- // - IP
- // - cookie
- // - configuration option?
+ /**
+ * Test if the current visitor is excluded from the statistics.
+ *
+ * Plugins can for example exclude visitors based on the
+ * - IP
+ * - If a given cookie is found
+ *
+ * @return bool True if the visit must not be saved, false otherwise
+ */
private function isExcluded()
{
$excluded = 0;
@@ -51,6 +80,10 @@ class Piwik_LogStats_Visit
return false;
}
+ /**
+ * Returns the cookie name used for the Piwik LogStats cookie
+ * @return string
+ */
private function getCookieName()
{
return Piwik_LogStats_Config::getInstance()->LogStats['cookie_name'] . $this->idsite;
@@ -159,6 +192,11 @@ class Piwik_LogStats_Visit
}
}
+ /**
+ * Gets the UserSettings information and returns them in an array of name => value
+ *
+ * @return array
+ */
private function getUserSettingsInformation()
{
// we already called this method before, simply returns the result
@@ -238,6 +276,7 @@ class Piwik_LogStats_Visit
/**
* Returns true if the last action was done during the last 30 minutes
+ * @return bool
*/
private function isLastActionInTheSameVisit()
{
@@ -245,13 +284,18 @@ class Piwik_LogStats_Visit
>= ($this->getCurrentTimestamp() - Piwik_LogStats::VISIT_STANDARD_LENGTH);
}
+ /**
+ * Returns true if the recognizeTheVisitor() method did recognize the visitor
+ */
private function isVisitorKnown()
{
return $this->visitorKnown === true;
}
/**
- * Once we have the visitor information, we have to define if the visit is a new or a known visit.
+ * Main algorith to handle the visit.
+ *
+ * Once we have the visitor information, we have to define if the visit is a new or a known visit.
*
* 1) When the last action was done more than 30min ago,
* or if the visitor is new, then this is a new visit.
@@ -261,14 +305,11 @@ class Piwik_LogStats_Visit
*
* NB:
* - In the case of a new visit, then the time spent
- * during the last action of the previous visit is unknown.
+ * during the last action of the previous visit is unknown.
*
* - In the case of a new visit but with a known visitor,
* we can set the 'returning visitor' flag.
*
- */
-
- /**
* In all the cases we set a cookie to the visitor with the new information.
*/
public function handle()
@@ -294,6 +335,9 @@ class Piwik_LogStats_Visit
$this->updateCookie();
}
+ /**
+ * Update the cookie information.
+ */
private function updateCookie()
{
printDebug("We manage the cookie...");
@@ -526,6 +570,7 @@ class Piwik_LogStats_Visit
* - referer_url : the same for all the referer types
*
*/
+ //TODO split this big method getRefererInformation into small methods
private function getRefererInformation()
{
// bool that says if the referer detection is done
@@ -720,11 +765,20 @@ class Piwik_LogStats_Visit
return $refererInformation;
}
+ /**
+ * Returns a MD5 of all the configuration settings
+ * @return string
+ */
private function getConfigHash( $os, $browserName, $browserVersion, $resolution, $colorDepth, $plugin_Flash, $plugin_Director, $plugin_RealPlayer, $plugin_Pdf, $plugin_WindowsMedia, $plugin_Java, $plugin_Cookie, $ip, $browserLang)
{
return md5( $os . $browserName . $browserVersion . $resolution . $colorDepth . $plugin_Flash . $plugin_Director . $plugin_RealPlayer . $plugin_Pdf . $plugin_WindowsMedia . $plugin_Java . $plugin_Cookie . $ip . $browserLang );
}
+ /**
+ * Returns either
+ * - "-1" for a known visitor
+ * - a unique 32 char identifier
+ */
private function getVisitorUniqueId()
{
if($this->isVisitorKnown())
diff --git a/modules/Period.php b/modules/Period.php
index f3082d2014..a5b7908f17 100644
--- a/modules/Period.php
+++ b/modules/Period.php
@@ -3,14 +3,14 @@
* Creating a new Piwik_Period
*
* Every overloaded method must start with the code
- if(!$this->subperiodsProcessed)
- {
- $this->generate();
- }
- that checks whether the subperiods have already been computed.
- This is for performance improvements, computing the subperiods is done a per demand basis.
-
-
+ * if(!$this->subperiodsProcessed)
+ * {
+ * $this->generate();
+ * }
+ * that checks whether the subperiods have already been computed.
+ * This is for performance improvements, computing the subperiods is done a per demand basis.
+ *
+ * @package Piwik
*/
abstract class Piwik_Period
{
diff --git a/modules/Piwik.php b/modules/Piwik.php
index 4a7984fc3a..0931d2d6ae 100755
--- a/modules/Piwik.php
+++ b/modules/Piwik.php
@@ -1,5 +1,8 @@
<?php
-
+/**
+ *
+ * @package Piwik
+ */
require_once "Config.php";
require_once "Zend/Db.php";
require_once "Zend/Db/Table.php";
@@ -23,7 +26,29 @@ class Piwik
Zend_Registry::get('logger_message')->log( "<br>" . PHP_EOL);
}
+ static function displayZendProfiler()
+ {
+ $profiler = Zend_Registry::get('db')->getProfiler();
+
+ $totalTime = $profiler->getTotalElapsedSecs();
+ $queryCount = $profiler->getTotalNumQueries();
+ $longestTime = 0;
+ $longestQuery = null;
+ foreach ($profiler->getQueryProfiles() as $query) {
+ if ($query->getElapsedSecs() > $longestTime) {
+ $longestTime = $query->getElapsedSecs();
+ $longestQuery = $query->getQuery();
+ }
+ }
+
+ echo '<br>Executed ' . $queryCount . ' queries in ' . $totalTime . ' seconds' . "\n";
+ echo '<br>Average query length: ' . $totalTime / $queryCount . ' seconds' . "\n";
+ echo '<br>Queries per second: ' . $queryCount / $totalTime . "\n";
+ echo '<br>Longest query length: ' . $longestTime . "\n";
+ echo '<br>Longest query: <br>' . $longestQuery . "\n";
+ }
+
static public function error($message = '')
{
trigger_error($message, E_USER_ERROR);
@@ -46,6 +71,37 @@ class Piwik
$queryCount = $profiler->getTotalNumQueries();
Piwik::log("Total queries = $queryCount (total sql time = ".round($totalTime,2)."s)");
}
+
+ static public function printLogStatsSQLProfiling()
+ {
+ function maxSumMsFirst($a,$b)
+ {
+ return $a['sum_time_ms'] < $b['sum_time_ms'];
+ }
+
+ $db = Zend_Registry::get('db');
+ $all = $db->fetchAll(' SELECT *, sum_time_ms / count as avg_time_ms
+ FROM '.Piwik::prefixTable('log_profiling')
+ );
+ usort($all, 'maxSumMsFirst');
+
+ $str='<br><br>Query Profiling<br>----------------------<br>';
+ foreach($all as $infoQuery)
+ {
+ $query = $infoQuery['query'];
+ $count = $infoQuery['count'];
+ $sum_time_ms = $infoQuery['sum_time_ms'];
+ $avg_time_ms = round($infoQuery['avg_time_ms'],1);
+ $query = str_replace("\t", "", $query);
+
+ $str .= " $query <br>
+ $count times, <b>$sum_time_ms ms total</b><br>
+ $avg_time_ms ms average<br>
+ <br>";
+ }
+
+ print($str);
+ }
static public function printMemoryUsage( $prefixString = null )
{
diff --git a/modules/Plugin.php b/modules/Plugin.php
index 057bdc26bb..f1535acc18 100644
--- a/modules/Plugin.php
+++ b/modules/Plugin.php
@@ -3,6 +3,8 @@
/**
* Abstract class to define a Piwik_Plugin.
* Any plugin has to at least implement the abstract methods of this class.
+ *
+ * @package Piwik
*/
abstract class Piwik_Plugin
{
diff --git a/modules/PluginsManager.php b/modules/PluginsManager.php
index 090f4cc7f2..c1fbcebe87 100644
--- a/modules/PluginsManager.php
+++ b/modules/PluginsManager.php
@@ -22,7 +22,8 @@
* - generally a plugin method can modify data (filter) and add/remove data
*
*
- */
+ * @package Piwik
+ */
require_once "Plugin.php";
require_once "Event/Dispatcher.php";
diff --git a/modules/Site.php b/modules/Site.php
index aa892465bf..41c75dcd0b 100644
--- a/modules/Site.php
+++ b/modules/Site.php
@@ -1,5 +1,8 @@
<?php
-
+/**
+ *
+ * @package Piwik
+ */
class Piwik_Site
{
protected $id = null;
diff --git a/modules/SitesManager.php b/modules/SitesManager.php
index d6bac0a111..a481729c47 100755
--- a/modules/SitesManager.php
+++ b/modules/SitesManager.php
@@ -1,5 +1,8 @@
<?php
-
+/**
+ *
+ * @package Piwik
+ */
require_once "API/APIable.php";
class Piwik_SitesManager_API extends Piwik_Apiable
diff --git a/modules/TablePartitioning.php b/modules/TablePartitioning.php
index 59a1d91771..edd6f7b8a7 100644
--- a/modules/TablePartitioning.php
+++ b/modules/TablePartitioning.php
@@ -1,5 +1,8 @@
<?php
-
+/**
+ *
+ * @package Piwik
+ */
abstract class Piwik_TablePartitioning
{
protected $tableName = null;
diff --git a/modules/Timer.php b/modules/Timer.php
index d26a8cef07..27b9d4c80a 100644
--- a/modules/Timer.php
+++ b/modules/Timer.php
@@ -1,4 +1,8 @@
<?php
+/**
+ *
+ * @package Piwik
+ */
class Piwik_Timer
{
private $m_Start;
diff --git a/modules/Translate.php b/modules/Translate.php
index 47a09fc1cf..679a3e48be 100644
--- a/modules/Translate.php
+++ b/modules/Translate.php
@@ -1,4 +1,8 @@
<?php
+/**
+ *
+ * @package Piwik
+ */
class Piwik_Translate
{
static private $instance = null;
diff --git a/modules/Url.php b/modules/Url.php
new file mode 100644
index 0000000000..aa7806e0d5
--- /dev/null
+++ b/modules/Url.php
@@ -0,0 +1,68 @@
+<?php
+class Piwik_Url
+{
+
+ static public function getCurrentUrl()
+ {
+ return self::getCurrentHost()
+ . self::getCurrentScriptName()
+ . self::getCurrentQueryString();
+ }
+
+ static public function getCurrentScriptName()
+ {
+ $url = '';
+ if( !empty($_SERVER['PATH_INFO']) )
+ {
+ $url = $_SERVER['PATH_INFO'];
+ }
+ else if( !empty($_SERVER['REQUEST_URI']) )
+ {
+ if( ($pos = strpos($_SERVER['REQUEST_URI'], "?")) !== false )
+ {
+ $url = substr($_SERVER['REQUEST_URI'], 0, $pos);
+ }
+ else
+ {
+ $url = $_SERVER['REQUEST_URI'];
+ }
+ }
+
+ if(empty($url))
+ {
+ $url = $_SERVER['SCRIPT_NAME'];
+ }
+ return $url;
+ }
+
+ static public function getCurrentHost()
+ {
+ if(isset($_SERVER['HTTPS'])
+ && ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == true)
+ )
+ {
+ $url = 'https';
+ }
+ else
+ {
+ $url = 'http';
+ }
+
+ $url .= '://' . $_SERVER['HTTP_HOST'];
+ return $url;
+ }
+
+
+ static public function getCurrentQueryString()
+ {
+ $url = '';
+ if(isset($_SERVER['QUERY_STRING'])
+ && !empty($_SERVER['QUERY_STRING']))
+ {
+ $url .= "?".$_SERVER['QUERY_STRING'];
+ }
+ return $url;
+ }
+}
+
+//echo Piwik_Url::getCurrentCompleteUrl(); \ No newline at end of file
diff --git a/modules/UsersManager.php b/modules/UsersManager.php
index 769f8ac00e..78317bc3db 100755
--- a/modules/UsersManager.php
+++ b/modules/UsersManager.php
@@ -1,4 +1,8 @@
<?php
+/**
+ *
+ * @package Piwik
+ */
Zend_Loader::loadClass("Piwik_Access");
class Piwik_UsersManager_API extends Piwik_Apiable
@@ -459,7 +463,7 @@ class Piwik_UsersManager_API extends Piwik_Apiable
* @param string login
* @param string password
*/
- static private function getTokenAuth($userLogin, $password)
+ static public function getTokenAuth($userLogin, $password)
{
return md5($userLogin . $password );