diff options
author | mattpiwik <matthieu.aubry@gmail.com> | 2008-08-04 03:53:22 +0400 |
---|---|---|
committer | mattpiwik <matthieu.aubry@gmail.com> | 2008-08-04 03:53:22 +0400 |
commit | 42b52b6d8a88b3fa4c4f3978c4e7bf00b1eac778 (patch) | |
tree | e60f0a9ebcbc8ab2c9f45031284bec17cc532523 /modules | |
parent | 6e636d8a92748657ccb1dde7def6ad174a7c8b75 (diff) |
- renamed modules/ directory in core/
- cleaning admin UI
- adding widgetize module
- cleaning template architecture
git-svn-id: http://dev.piwik.org/svn/trunk@586 59fd770c-687e-43c8-a1e3-f5a4ff64c105
Diffstat (limited to 'modules')
124 files changed, 0 insertions, 22246 deletions
diff --git a/modules/API/APIable.php b/modules/API/APIable.php deleted file mode 100755 index 3912954ec5..0000000000 --- a/modules/API/APIable.php +++ /dev/null @@ -1,55 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_API - */ - - -require_once "Archive.php"; -/** - * This class is the parent class of all the modules that can be called using the API Proxy. - * For example a plugin "Provider" can publish its API by creating a file plugins/Provider/API.php - * that is extending this Piwik_Apiable class. - * All the Piwik_Apiable classes are read and loaded by the Piwik_API_Proxy class. - * The public methods of this class are published in the API and are then callable using the API module. - * The parameters of the function are read directly from the GET request (they must have the same name). - * - * For example - * public function helloWorld($text) { return "hello " . $text; } - * call be called using - * ?module=API&method=PluginName.helloWorld&text=world! - * - * See the documentation on http://dev.piwik.org > API - * - * @package Piwik_API - * @see Piwik_API_Proxy - */ - -abstract class Piwik_Apiable -{ - /** - * This array contains the name of the methods of the class we don't want to publish in the API. - * By default only public methods are published. Names of public methods in this array won't be published. - * - * @var array of strings - */ - static public $methodsNotToPublish = array(); - - /** - * @see self::$methodsNotToPublish - * @param string Method name not to be published - */ - protected function doNotPublishMethod( $methodName ) - { - if(!method_exists($this, $methodName)) - { - throw new Exception("The method $methodName doesn't exist so it can't be added to the list of the methods not to be published in the API."); - } - $this->methodsNotToPublish[] = $methodName; - } -} diff --git a/modules/API/Proxy.php b/modules/API/Proxy.php deleted file mode 100755 index ef6ea1812a..0000000000 --- a/modules/API/Proxy.php +++ /dev/null @@ -1,481 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_API - */ - - -/** - * The API Proxy receives all the API calls requests and forwards them to the given module. - * - * It registers all the APIable modules (@see Piwik_Apiable) - * The class checks that a call to the API has the correct number of parameters. - * The proxy is a singleton that has the knowledge of every method available, their parameters and default values. - * - * It can also log the performances of the API calls (time spent, parameter values, etc.) - * - * @package Piwik_API - */ -class Piwik_API_Proxy -{ - static $classCalled = null; - - // array of already registered modules names - protected $alreadyRegistered = array(); - - private $api = array(); - - // when a parameter doesn't have a default value we use this constant - const NO_DEFAULT_VALUE = null; - - static private $instance = null; - protected function __construct() - {} - - /** - * Singleton, returns instance - * - * @return Piwik_API_Proxy - */ - static public function getInstance() - { - if (self::$instance == null) - { - $c = __CLASS__; - self::$instance = new $c(); - } - return self::$instance; - } - - /** - * Registers the API information of a given module. - * - * The module to be registered must be - * - extending the Piwik_Apiable class - * - a singleton (providing a getInstance() method) - * - the API file must be located in plugins/ModuleName/API.php - * for example plugins/Referers/API.php - * - * The method will introspect the methods, their parameters, etc. - * - * @param string ModuleName eg. "UserSettings" - */ - public function registerClass( $fileName ) - { - if(isset($this->alreadyRegistered[$fileName])) - { - return; - } - - $potentialPaths = array( "plugins/". $fileName ."/API.php", ); - - $found = false; - foreach($potentialPaths as $path) - { - if(Zend_Loader::isReadable($path)) - { - require_once $path; - $found = true; - break; - } - } - - if(!$found) - { - throw new Exception("API module $fileName not found."); - } - - $class= $this->getClassNameFromModule($fileName); - - $rClass = new ReflectionClass($class); - - // check that it is a subclass of Piwik_APIable - if(!$rClass->isSubclassOf(new ReflectionClass("Piwik_Apiable"))) - { - throw new Exception("To publish its public methods in the API, the class '$class' must be a subclass of 'Piwik_Apiable'."); - } - - // check that is is singleton - $this->checkClassIsSingleton($class); - - $rMethods = $rClass->getMethods(); - foreach($rMethods as $method) - { - // use this trick to read the static attribute of the class - // $class::$methodsNotToPublish doesn't work - $variablesClass = get_class_vars($class); - $variablesClass['methodsNotToPublish'][] = 'getInstance'; - - if($method->isPublic() - && !$method->isConstructor() - && !in_array($method->getName(), $variablesClass['methodsNotToPublish'] ) - ) - { - $name = $method->getName(); - - $parameters = $method->getParameters(); - - $aParameters = array(); - foreach($parameters as $parameter) - { - $nameVariable = $parameter->getName(); - - $defaultValue = Piwik_API_Proxy::NO_DEFAULT_VALUE; - if($parameter->isDefaultValueAvailable()) - { - $defaultValue = $parameter->getDefaultValue(); - } - - $aParameters[$nameVariable] = $defaultValue; - } - $this->api[$class][$name]['parameters'] = $aParameters; - $this->api[$class][$name]['numberOfRequiredParameters'] = $method->getNumberOfRequiredParameters(); - } - } - - $this->alreadyRegistered[$fileName] = true; - } - - /** - * Returns the 'moduleName' part of 'Piwik_moduleName_API' classname - * - * @param string moduleName - * @return string className - */ - protected function getModuleNameFromClassName( $className ) - { - $start = strpos($className, '_') + 1; - return substr($className, $start , strrpos($className, '_') - $start); - } - - /** - * Returns a string containing links to examples on how to call a given method on a given API - * It will export links to XML, CSV, HTML, JSON, PHP, etc. - * It will not export links for methods such as deleteSite or deleteUser - * - * @param string the class - * @param methodName the method - * @return string|false when not possible - */ - public function getExampleUrl($class, $methodName, $parametersToSet = array()) - { - $knowExampleDefaultParametersValues = array( - 'access' => 'view', - 'idSite' => '1', - 'userLogin' => 'test', - 'password' => 'passwordExample', - 'passwordMd5ied' => 'passwordExample', - 'email' => 'test@example.org', - - 'siteName' => 'new example website', - 'urls' => 'http://example.org', // used in addSite, updateSite - - 'period' => 'day', - 'date' => 'today', - ); - - foreach($parametersToSet as $name => $value) - { - $knowExampleDefaultParametersValues[$name] = $value; - } - - // no links for these method names - $doNotPrintExampleForTheseMethods = array( - 'deleteSite', - 'deleteUser', - ); - - if(in_array($methodName,$doNotPrintExampleForTheseMethods)) - { - return false; - } - - - // we try to give an URL example to call the API - $aParameters = $this->getParametersList($class, $methodName); - $moduleName = $this->getModuleNameFromClassName($class); - $urlExample = '?module=API&method='.$moduleName.'.'.$methodName.'&'; - foreach($aParameters as $nameVariable=> $defaultValue) - { - // if there isn't a default value for a given parameter, - // we need a 'know default value' or we can't generate the link - if($defaultValue === Piwik_API_Proxy::NO_DEFAULT_VALUE) - { - if(isset($knowExampleDefaultParametersValues[$nameVariable])) - { - $exampleValue = $knowExampleDefaultParametersValues[$nameVariable]; - $urlExample .= $nameVariable . '=' . $exampleValue . '&'; - } - else - { - return false; - } - } - - } - - return substr($urlExample,0,-1); - } - - /** - * Returns a HTML page containing help for all the successfully loaded APIs. - * - * For each module it will return a mini help with the method names, parameters to give, - * links to get the result in Xml/Csv/etc - * - * @return string - */ - public function getAllInterfaceString( $outputExampleUrls = true, $prefixUrls = '' ) - { - $str = ''; - $token_auth = "&token_auth=" . Piwik::getCurrentUserTokenAuth(); - foreach($this->api as $class => $info) - { - $moduleName = $this->getModuleNameFromClassName($class); - $str .= "\n<h2 id='$moduleName'>Module ".$moduleName."</h2>"; - - foreach($info as $methodName => $infoMethod) - { - $params = $this->getStrListParameters($class, $methodName); - $str .= "\n" . "- <b>$moduleName.$methodName " . $params . "</b>"; - $str .= '<small>'; - - if($outputExampleUrls) - { - // we prefix all URLs with $prefixUrls - // used when we include this output in the Piwik official documentation for example - $exampleUrl = $this->getExampleUrl($class, $methodName); - if($exampleUrl !== false) - { - $lastNUrls = ''; - if( ereg('(&period)|(&date)',$exampleUrl)) - { - $exampleUrlRss1 = $prefixUrls . $this->getExampleUrl($class, $methodName, array('date' => 'last10')) ; - $exampleUrlRss2 = $prefixUrls . $this->getExampleUrl($class, $methodName, array('date' => 'last5','period' => 'week',)); - $lastNUrls = ", RSS of the last <a target=_blank href='$exampleUrlRss1&format=rss$token_auth'>10 days</a>, <a target=_blank href='$exampleUrlRss2&format=Rss'>5 weeks</a>, - XML of the <a target=_blank href='$exampleUrlRss1&format=xml$token_auth'>last 10 days</a>"; - } - $exampleUrl = $prefixUrls . $exampleUrl ; - $str .= " <span class=\"example\">[ Example in - <a target=_blank href='$exampleUrl&format=xml$token_auth'>XML</a>, - <a target=_blank href='$exampleUrl&format=PHP&prettyDisplay=true$token_auth'>PHP</a>, - <a target=_blank href='$exampleUrl&format=JSON$token_auth'>Json</a>, - <a target=_blank href='$exampleUrl&format=Csv$token_auth'>Csv</a>, - <a target=_blank href='$exampleUrl&format=Html$token_auth'>Basic html</a> - $lastNUrls - ]</span>"; - } - else - { - $str .= " [ No example available ]"; - } - } - $str .= '</small>'; - $str .= "\n<br>"; - } - } - return $str; - } - - /** - * Returns the methods $class.$name parameters (and default value if provided) as a string. - * - * @param string The class name - * @param string The method name - * @return string For example "(idSite, period, date = 'today')" - */ - private function getStrListParameters($class, $name) - { - $aParameters = $this->getParametersList($class, $name); - $asParameters = array(); - foreach($aParameters as $nameVariable=> $defaultValue) - { - $str = $nameVariable; - if($defaultValue !== Piwik_API_Proxy::NO_DEFAULT_VALUE) - { - $str .= " = '$defaultValue'"; - } - $asParameters[] = $str; - } - $sParameters = implode(", ", $asParameters); - return "($sParameters)"; - } - - /** - * Returns the parameters names and default values for the method $name - * of the class $class - * - * @param string The class name - * @param string The method name - * @return array Format array( - * 'testParameter' => null, // no default value - * 'life' => 42, // default value = 42 - * 'date' => 'yesterday', - * ); - */ - public function getParametersList($class, $name) - { - return $this->api[$class][$name]['parameters']; - } - - /** - * Returns the number of required parameters (parameters without default values). - * - * @param string The class name - * @param string The method name - * @return int The number of required parameters - */ - private function getNumberOfRequiredParameters($class, $name) - { - return $this->api[$class][$name]['numberOfRequiredParameters']; - } - - /** - * Returns true if the method is found in the API of the given class name. - * - * @param string The class name - * @param string The method name - * @return bool - */ - private function isMethodAvailable( $className, $methodName) - { - return isset($this->api[$className][$methodName]); - } - - - /** - * Checks that the count of the given parameters do match with the count of the required ones - * - * @param string The class name - * @param string The method name - * @param array - * @throws exception If less parameters than required were given - */ - private function checkNumberOfParametersMatch($className, $methodName, $parameters) - { - $nbParamsGiven = count($parameters); - $nbParamsRequired = $this->getNumberOfRequiredParameters($className, $methodName); - - if($nbParamsGiven < $nbParamsRequired) - { - throw new Exception("The number of parameters provided ($nbParamsGiven) is less than the number of required parameters ($nbParamsRequired) for this method. - Please check the method API."); - } - } - - /** - * Checks that the class is a Singleton (presence of the getInstance() method) - * - * @param string The class name - * @throws exception If the class is not a Singleton - */ - private function checkClassIsSingleton($className) - { - if(!method_exists($className, "getInstance")) - { - throw new Exception("Objects that provide an API must be Singleton and have a 'static public function getInstance()' method."); - } - } - - /** - * Checks that the method exists in the class - * - * @param string The class name - * @param string The method name - * @throws exception If the method is not found - */ - public function checkMethodExists($className, $methodName) - { - if(!$this->isMethodAvailable($className, $methodName)) - { - throw new Exception("The method '$methodName' does not exist or is not available in the module '".$className."'."); - } - } - - /** - * Returns the API class name given the module name. - * - * For exemple for $module = 'Referers' it returns 'Piwik_Referers_API' - * Piwik_Referers_API is the class that extends Piwik_Apiable - * and that contains the methods to be published in the API. - * - * @param string module name - * @return string class name - */ - protected function getClassNameFromModule($module) - { - $class = Piwik::prefixClass($module ."_API"); - return $class; - } - - /** - * Magic method used to set a flag telling the module named currently being called - * - */ - public function __get($name) - { - self::$classCalled = $name; - return $this; - } - - /** - * Method always called when making an API request. - * It checks several things before actually calling the real method on the given module. - * - * It also logs the API calls, with the parameters values, the returned value, the performance, etc. - * You can enable logging in config/global.ini.php (log_api_call) - * - * @param string The method name - * @param array The parameters - * - * @throws Piwik_Access_NoAccessException - */ - public function __call($methodName, $parameterValues ) - { - $returnedValue = null; - - try { - $this->registerClass(self::$classCalled); - - $className = $this->getClassNameFromModule(self::$classCalled); - - // instanciate the object - $object = call_user_func(array($className, "getInstance")); - - // check method exists - $this->checkMethodExists($className, $methodName); - - // first check number of parameters do match - $this->checkNumberOfParametersMatch($className, $methodName, $parameterValues); - - // start the timer - $timer = new Piwik_Timer; - - // call the method - $returnedValue = call_user_func_array(array($object, $methodName), $parameterValues); - - // log the API Call - $parameterNamesDefaultValues = $this->getParametersList($className, $methodName); - Zend_Registry::get('logger_api_call')->log( - self::$classCalled, - $methodName, - $parameterNamesDefaultValues, - $parameterValues, - $timer->getTimeMs(), - $returnedValue - ); - } - catch( Piwik_Access_NoAccessException $e) { - throw $e; - } - - self::$classCalled = null; - - return $returnedValue; - } -} diff --git a/modules/API/Request.php b/modules/API/Request.php deleted file mode 100644 index 74b546affb..0000000000 --- a/modules/API/Request.php +++ /dev/null @@ -1,588 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * - * @package Piwik_API - */ - - -/** - * An API request is the object used to make a call to the API and get the result. - * The request has the format of a normal GET request, ie. parameter_1=X¶meter_2=Y - * - * You can use this object from anywhere in piwik (inside plugins for example). - * You can even call it outside of piwik using the REST API over http - * or in a php script on the same server as piwik, by including piwik/index.php - * (see examples in the documentation http://dev.piwik.org/trac/wiki/API) - * - * Example: - * $request = new Piwik_API_Request(' - * method=UserSettings.getWideScreen - * &idSite=1 - * &date=yesterday - * &period=week - * &format=xml - * &filter_limit=5 - * &filter_offset=0 - * '); - * $result = $request->process(); - * echo $result; - * - * @see http://dev.piwik.org/trac/wiki/API - * @package Piwik_API - */ -class Piwik_API_Request -{ - protected $outputFormatRequested; - - /** - * Constructs the request to the API, given the request url - * - * @param string GET request that defines the API call (must at least contain a "method" parameter) - * Example: method=UserSettings.getWideScreen&idSite=1&date=yesterday&period=week&format=xml - * If a request is not provided, then we use the $_REQUEST superglobal and fetch - * the values directly from the HTTP GET query. - */ - function __construct($request = null) - { - $requestArray = $_REQUEST; - - // If an array is specified we use it - if(!is_null($request)) - { - $request = trim($request); - $request = str_replace(array("\n","\t"),'', $request); - parse_str($request, $requestArray); - - // but we handle the case when an array is specified but we also want - // to look for the value in the _REQUEST - $requestArray = array_merge( $_REQUEST, $requestArray); - } - - // remove all spaces from parameters values (when calling internally the API for example) - foreach($requestArray as &$element) - { - // sometimes GET parameters can be arrays but we assume module accepting arrays are correctly handling spaces - if(!is_array($element)) - { - $element = trim($element); - } - } - - $this->requestToUse = $requestArray; - } - - /** - * Returns array( $class, $method) from the given string $class.$method - * - * @return array - * @throws exception if the name is invalid - */ - private function extractModuleAndMethod($parameter) - { - $a = explode('.',$parameter); - if(count($a) != 2) - { - throw new Exception("The method name is invalid. Must be on the form 'module.methodName'"); - } - return $a; - } - - - /** - * Handles the request to the API. - * It first checks that the method called (parameter 'method') is available in the module (it means that the method exists and is public) - * It then reads the parameters from the request string and throws an exception if there are missing parameters. - * It then calls the API Proxy which will call the requested method. - * - * @see the method handleReturnedValue() for the data post process logic - * - * @return mixed The data resulting from the API call - */ - public function process() - { - try { - - // read the format requested for the output data - $this->outputFormatRequested = Piwik_Common::getRequestVar('format', 'xml', 'string', $this->requestToUse); - $this->outputFormatRequested = strtolower($this->outputFormatRequested); - - // read parameters - $moduleMethod = Piwik_Common::getRequestVar('method', null, null, $this->requestToUse); - - list($module, $method) = $this->extractModuleAndMethod($moduleMethod); - - if(!Piwik_PluginsManager::getInstance()->isPluginEnabled($module)) - { - throw new Exception_PluginDeactivated($module); - } - // call the method via the API_Proxy class - $api = Piwik_Api_Proxy::getInstance(); - $api->registerClass($module); - - // read method to call meta information - $className = "Piwik_" . $module . "_API"; - - // check method exists - $api->checkMethodExists($className, $method); - - // get the list of parameters required by the method - $parameters = $api->getParametersList($className, $method); - - // load the parameters from the request URL - $finalParameters = $this->getRequestParametersArray( $parameters ); - - // call the method - $returnedValue = call_user_func_array( array( $api->$module, $method), $finalParameters ); - - // post process the data - $toReturn = $this->handleReturnedValue( $returnedValue ); - - - } catch(Exception $e ) { - - // if it is not a direct API call, we are requesting the original data structure - // and we actually are handling this exception at the top level in the FrontController - if($this->outputFormatRequested == 'original') - { - throw $e; - } - $message = $e->getMessage(); - - $toReturn = $this->getExceptionOutput( $message, $this->outputFormatRequested); - - } - - return $toReturn; - } - - /** - * Returns the values of the current request - * - * @param array Parameters array of the method called. Contains name and default values of the required parameters - * @return array Values of the given parameters - * @throws exception If there is a missing parameter - */ - protected function getRequestParametersArray( $parameters ) - { - $finalParameters = array(); - foreach($parameters as $name => $defaultValue) - { - try{ - // there is a default value specified - if($defaultValue !== Piwik_API_Proxy::NO_DEFAULT_VALUE) - { - $requestValue = Piwik_Common::getRequestVar($name, $defaultValue, null, $this->requestToUse); - } - else - { - $requestValue = Piwik_Common::getRequestVar($name, null, null, $this->requestToUse); - } - } catch(Exception $e) { - throw new Exception("The required variable '$name' is not correct or has not been found in the API Request. Add the parameter '&$name=' (with a value) in the URL."); - } - $finalParameters[] = $requestValue; - } - return $finalParameters; - } - - /** - * This method post processes the data resulting from the API call. - * - * - If the data resulted from the API call is a Piwik_DataTable then - * - we apply the standard filters if the parameters have been found - * in the URL. For example to offset,limit the Table you can add the following parameters to any API - * call that returns a DataTable: filter_limit=10&filter_offset=20 - * - we apply the filters that have been previously queued on the DataTable - * @see Piwik_DataTable::queueFilter() - * - we apply the renderer that generate the DataTable in a given format (XML, PHP, HTML, JSON, etc.) - * the format can be changed using the 'format' parameter in the request. - * Example: format=xml - * - * - If there is nothing returned (void) we display a standard success message - * - * - If there is a PHP array returned, we try to convert it to a dataTable - * It is then possible to convert this datatable to any requested format (xml/etc) - * - * - If a bool is returned we convert to a string (true is displayed as 'true' false as 'false') - * - * - If an integer / float is returned, we simply return it - * - * @throws Exception If an object/resource is returned, if any of conversion fails, etc. - * - * @param mixed The initial returned value, before post process - * @return mixed Usually a string, but can still be a PHP data structure if the format requested is 'original' - */ - protected function handleReturnedValue( $returnedValue ) - { - $toReturn = $returnedValue; - - // If the returned value is an object DataTable we - // apply the set of generic filters if asked in the URL - // and we render the DataTable according to the format specified in the URL - if($returnedValue instanceof Piwik_DataTable - || $returnedValue instanceof Piwik_DataTable_Array) - { - if($returnedValue instanceof Piwik_DataTable) - { - $this->applyDataTableGenericFilters($returnedValue); - } - elseif($returnedValue instanceof Piwik_DataTable_Array) - { - $tables = $returnedValue->getArray(); - foreach($tables as $table) - { - $this->applyDataTableGenericFilters($table); - } - } - - // if the flag disable_queued_filters is defined we skip the filters that were queued - // useful in some very rare cases but better to use this than a bad hack on the data returned... - if(Piwik_Common::getRequestVar('disable_queued_filters', 'false', 'string', $this->requestToUse) == 'false') - { - $returnedValue->applyQueuedFilters(); - } - - $toReturn = $this->getRenderedDataTable($returnedValue); - } - - // Case nothing returned (really nothing was 'return'ed), - // => the operation was successful - elseif(!isset($toReturn)) - { - $toReturn = $this->getStandardSuccessOutput($this->outputFormatRequested); - } - - // Case an array is returned from the API call, we convert it to the requested format - // - if calling from inside the application (format = original) - // => the data stays unchanged (ie. a standard php array or whatever data structure) - // - if any other format is requested, we have to convert this data structure (which we assume - // to be an array) to a DataTable in order to apply the requested DataTable_Renderer (for example XML) - elseif(is_array($toReturn)) - { - if($this->outputFormatRequested == 'original') - { - // we handle the serialization. Because some php array have a very special structure that - // couldn't be converted with the automatic DataTable->loadFromSimpleArray - // the user may want to request the original PHP data structure serialized by the API - // in case he has to setup serialize=1 in the URL - if($this->caseRendererPHPSerialize( $defaultSerialize = 0)) - { - $toReturn = serialize($toReturn); - } - } - else - { - $dataTable = new Piwik_DataTable(); - $dataTable->loadFromSimpleArray($toReturn); - $toReturn = $this->getRenderedDataTable($dataTable); - } - } - // bool // integer // float // object is serialized - // NB: null value is already handled by the isset() test above - else - { - // original data structure requested, we return without process - if( $this->outputFormatRequested == 'original' ) - { - return $toReturn; - } - - if( $toReturn === true ) - { - $toReturn = 'true'; - } - elseif( $toReturn === false ) - { - $toReturn = 'false'; - } - elseif( is_object($toReturn) - || is_resource($toReturn) - ) - { - return $this->getExceptionOutput( ' The API cannot handle this data structure. You can get the data internally by directly using the class.', $this->outputFormatRequested); - } - - require_once "DataTable/Simple.php"; - $dataTable = new Piwik_DataTable_Simple(); - $dataTable->loadFromArray( array($toReturn) ); - $toReturn = $this->getRenderedDataTable($dataTable); - } - return $toReturn; - } - - /** - * Returns a success $message in the requested $format - * - * @param string $format xml/json/php/csv - * @param string $message - * @return string - */ - protected function getStandardSuccessOutput($format, $message = 'ok') - { - switch($format) - { - case 'xml': - @header("Content-Type: text/xml;charset=utf-8"); - $return = - '<?xml version="1.0" encoding="utf-8" ?>'. - '<result>'. - ' <success message="'.$message.'" />'. - '</result>'; - break; - case 'json': - @header( "Content-type: application/json" ); - $return = '{"result":"success", "message":"'.$message.'"}'; - break; - case 'php': - $return = array('result' => 'success', 'message' => $message); - if($this->caseRendererPHPSerialize()) - { - $return = serialize($return); - } - break; - - case 'csv': - header("Content-type: application/vnd.ms-excel"); - header("Content-Disposition: attachment; filename=piwik-report-export.csv"); - $return = "message\n".$message; - break; - - default: - $return = 'Success:'.$message; - break; - } - - return $return; - } - - /** - * Returns an error $message in the requested $format - * - * @param string $format xml/json/php/csv - * @param string $message - * @return string - */ - function getExceptionOutput($message, $format) - { - switch($format) - { - case 'xml': - @header("Content-Type: text/xml;charset=utf-8"); - $return = - '<?xml version="1.0" encoding="utf-8" ?>'. - '<result>'. - ' <error message="'.htmlentities($message).'" />'. - '</result>'; - break; - case 'json': - @header( "Content-type: application/json" ); - // we remove the \n from the resulting string as this is not allowed in json - $message = str_replace("\n","",$message); - $return = '{"result":"error", "message":"'.htmlentities($message).'"}'; - break; - case 'php': - $return = array('result' => 'error', 'message' => $message); - if($this->caseRendererPHPSerialize()) - { - $return = serialize($return); - } - break; - default: - $return = 'Error: '.$message; - break; - } - - return $return; - } - - /** - * Apply the specified renderer to the DataTable - * - * @param Piwik_DataTable - * @return string - */ - protected function getRenderedDataTable($dataTable) - { - // Renderer - $format = Piwik_Common::getRequestVar('format', 'php', 'string', $this->requestToUse); - $format = strtolower($format); - - // if asked for original dataStructure - if($format == 'original') - { - // if the original dataStructure is a simpleDataTable and has only one row, we return the value - if($dataTable instanceof Piwik_DataTable_Simple - && $dataTable->getRowsCount() == 1) - { - return $dataTable->getRowFromId(0)->getColumn('value'); - } - - // the original data structure can be asked as serialized. - // but by default it's not serialized - if($this->caseRendererPHPSerialize( $defaultSerialize = 0)) - { - $dataTable = serialize($dataTable); - } - return $dataTable; - } - - $renderer = Piwik_DataTable_Renderer::factory($format); - $renderer->setTable($dataTable); - - if($format == 'php') - { - $renderer->setSerialize( $this->caseRendererPHPSerialize()); - } - - $toReturn = $renderer->render(); - return $toReturn; - } - - /** - * Returns true if the user requested to serialize the output data (&serialize=1 in the request) - * - * @param $defaultSerializeValue Default value in case the user hasn't specified a value - * @return bool - */ - protected function caseRendererPHPSerialize($defaultSerializeValue = 1) - { - $serialize = Piwik_Common::getRequestVar('serialize', $defaultSerializeValue, 'int', $this->requestToUse); - if($serialize) - { - return true; - } - else - { - return false; - } - } - - /** - * Returns an array containing the information of the generic Piwik_DataTable_Filter - * to be applied automatically to the data resulting from the API calls. - * - * @return array See the code for spec - */ - public static function getGenericFiltersInformation() - { - $genericFilters = array( - - 'Pattern' => array( - 'filter_column' => array('string'), - 'filter_pattern' => array('string'), - ), - 'PatternRecursive' => array( - 'filter_column_recursive' => array('string'), - 'filter_pattern_recursive' => array('string'), - ), - 'ExcludeLowPopulation' => array( - 'filter_excludelowpop' => array('string'), - 'filter_excludelowpop_value'=> array('float'), - ), - 'Sort' => array( - 'filter_sort_column' => array('string', Piwik_Archive::INDEX_NB_VISITS), - 'filter_sort_order' => array('string', Zend_Registry::get('config')->General->dataTable_default_sort_order), - ), - 'Limit' => array( - 'filter_offset' => array('integer', '0'), - 'filter_limit' => array('integer', Zend_Registry::get('config')->General->dataTable_default_limit), - ), - ); - - return $genericFilters; - } - - - /** - * Apply generic filters to the DataTable object resulting from the API Call. - * Disable this feature by setting the parameter disable_generic_filters to 1 in the API call request. - * - * @param Piwik_DataTable - * @return void - */ - protected function applyDataTableGenericFilters($dataTable) - { - if($dataTable instanceof Piwik_DataTable_Array ) - { - $tables = $dataTable->getArray(); - foreach($tables as $table) - { - $this->applyDataTableGenericFilters($table); - } - return; - } - - // Generic filters - // PatternFileName => Parameter names to match to constructor parameters - /* - * Order to apply the filters: - * 1 - Filter that remove filtered rows - * 2 - Filter that sort the remaining rows - * 3 - Filter that keep only a subset of the results - */ - $genericFilters = Piwik_API_Request::getGenericFiltersInformation(); - - // if the flag disable_generic_filters is defined we skip the generic filters - if(Piwik_Common::getRequestVar('disable_generic_filters', 'false', 'string', $this->requestToUse) != 'false') - { - return; - } - - foreach($genericFilters as $filterName => $parameters) - { - $filterParameters = array(); - $exceptionRaised = false; - - foreach($parameters as $name => $info) - { - // parameter type to cast to - $type = $info[0]; - - // default value if specified, when the parameter doesn't have a value - $defaultValue = null; - if(isset($info[1])) - { - $defaultValue = $info[1]; - } - - try { - $value = Piwik_Common::getRequestVar($name, $defaultValue, $type, $this->requestToUse); - settype($value, $type); - $filterParameters[] = $value; - } - catch(Exception $e) - { - $exceptionRaised = true; - break; - } - } - - if(!$exceptionRaised) - { - // a generic filter class name must follow this pattern - $class = "Piwik_DataTable_Filter_".$filterName; - - if($filterName == 'Limit') - { - $dataTable->setRowsCountBeforeLimitFilter(); - } - - // build the set of parameters for the filter - $filterParameters = array_merge(array($dataTable), $filterParameters); - - // make a reflection object - $reflectionObj = new ReflectionClass($class); - - // use Reflection to create a new instance, using the $args - $filter = $reflectionObj->newInstanceArgs($filterParameters); - } - } - } - -}
\ No newline at end of file diff --git a/modules/Access.php b/modules/Access.php deleted file mode 100755 index d2fc7bd563..0000000000 --- a/modules/Access.php +++ /dev/null @@ -1,326 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik - * - */ - -require_once 'SitesManager/API.php'; - -/** - * Class to handle User Access: - * - loads user access from the Piwik_Auth_Result object - * - provides easy to use API to check the permissions for the current (check* methods) - * - * 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 - */ - -class Piwik_Access -{ - /** - * Array of idsites available to the current user, indexed by permission level - * @see getSitesIdWith*() - * - * @var array - */ - protected $idsitesByAccess = null; - - /** - * Login of the current user - * - * @var string - */ - protected $login = null; - - /** - * token_auth of the current user - * - * @var string - */ - protected $token_auth = null; - - /** - * Defines if the current user is the super user - * @see isSuperUser() - * - * @var bool - */ - protected $isSuperUser = false; - - /** - * List of available permissions in Piwik - * - * @var array - */ - static private $availableAccess = array('noaccess', 'view', 'admin', 'superuser'); - - /** - * Authentification object (see Piwik_Auth) - * - * @var Piwik_Auth - */ - private $auth; - - /** - * 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( Piwik_Auth $auth ) - { - $this->auth = $auth; - } - - /** - * Loads the access levels for the current user. - * - * Calls 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() - { - $idsitesByAccess = array( 'view' => array(), 'admin' => array(), 'superuser' => array()); - - // access = array ( idsite => accessIdSite, idsite2 => accessIdSite2) - $result = $this->auth->authenticate(); - - if($result->isValid()) - { - $this->login = $result->getIdentity(); - $this->token_auth = $result->getTokenAuth(); - - // case the superUser is logged in - if($result->getCode() == Piwik_Auth_Result::SUCCESS_SUPERUSER_AUTH_CODE) - { - $this->isSuperUser = true; - $idsitesByAccess['superuser'] = Piwik_SitesManager_API::getAllSitesId(); - } - // valid authentification (normal user logged in) - else - { - $db = Zend_Registry::get('db'); - - // we join with site in case there are rows in access for an idsite that doesn't exist anymore - // (backward compatibility ; before we deleted the site without deleting rows in _access table) - $accessRaw = $db->fetchAll("SELECT access, t2.idsite - FROM ".Piwik::prefixTable('access'). " as t1 - JOIN ".Piwik::prefixTable('site')." as t2 USING (idsite) ". - " WHERE login=?", $this->login); - - foreach($accessRaw as $access) - { - $idsitesByAccess[$access['access']][] = $access['idsite']; - } - } - } - - $this->idsitesByAccess = $idsitesByAccess; - } - - /** - * We bypass the normal auth method and give the current user Super User rights. - * This should be very carefully used. - * - * @return void - */ - public function setSuperUser() - { - $this->isSuperUser = true; - $this->idsitesByAccess['superuser'] = Piwik_SitesManager_API::getAllSitesId(); - } - - /** - * Returns true if the current user is logged in as the super user - * - * @return bool - */ - public function isSuperUser() - { - return $this->isSuperUser; - } - - /** - * Returns the current user login - * @return string - */ - public function getLogin() - { - return $this->login; - } - - /** - * Returns the token_auth used to authenticate this user in the API - * @return string - */ - public function getTokenAuth() - { - return $this->token_auth; - } - - /** - * 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( - $this->idsitesByAccess['view'], - $this->idsitesByAccess['admin'], - $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( - $this->idsitesByAccess['admin'], - $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 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 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($idSites === 'all') - { - $idSites = $this->getSitesIdWithAtLeastViewAccess(); - } - if(!is_array($idSites)) - { - $idSites = Piwik_Site::getIdSitesFromIdSitesString($idSites); - } - $idSitesAccessible = $this->getSitesIdWithAdminAccess(); - foreach($idSites as $idsite) - { - if(!in_array($idsite, $idSitesAccessible)) - { - 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|string List of ID sites to check (integer, array of integers, string comma separated list of integers) - * @throws Exception If for any of the websites the user doesn't have an VIEW or ADMIN access - */ - public function checkUserHasViewAccess( $idSites ) - { - if($idSites === 'all') - { - $idSites = $this->getSitesIdWithAtLeastViewAccess(); - } - - if(!is_array($idSites)) - { - $idSites = Piwik_Site::getIdSitesFromIdSitesString($idSites); - } - $idSitesAccessible = $this->getSitesIdWithAtLeastViewAccess(); - - foreach($idSites as $idsite) - { - if(!in_array($idsite, $idSitesAccessible)) - { - throw new Piwik_Access_NoAccessException("You can't access this resource as it requires a 'view' access for the website id = $idsite."); - } - } - } -} - -/** - * - * Exception thrown when a user doesn't have sufficient access. - * - * @package Piwik - */ -class Piwik_Access_NoAccessException extends Exception -{}
\ No newline at end of file diff --git a/modules/Archive.php b/modules/Archive.php deleted file mode 100644 index 1d9d4d52b6..0000000000 --- a/modules/Archive.php +++ /dev/null @@ -1,224 +0,0 @@ -<?php
-/**
- * Piwik - Open source web analytics
- *
- * @link http://piwik.org
- * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later
- * @version $Id$
- *
- * @package Piwik
- */
-
-
-require_once 'Period.php';
-require_once 'Date.php';
-require_once 'ArchiveProcessing.php';
-require_once 'Archive/Single.php';
-
-/**
- * The archive object is used to query specific data for a day or a period of statistics for a given website.
- *
- * Example:
- * <pre>
- * $archive = Piwik_Archive::build($idSite = 1, $period = 'week', '2008-03-08' );
- * $dataTable = $archive->getDataTable('Provider_hostnameExt');
- * $dataTable->queueFilter('Piwik_DataTable_Filter_ReplaceColumnNames');
- * return $dataTable;
- * </pre>
- *
- * Example bis:
- * <pre>
- * $archive = Piwik_Archive::build($idSite = 3, $period = 'day', $date = 'today' );
- * $nbVisits = $archive->getNumeric('nb_visits');
- * return $nbVisits;
- * </pre>
- *
- * If the requested statistics are not yet processed, Archive uses ArchiveProcessing to archive the statistics.
- *
- * @package Piwik
- * @subpackage Piwik_Archive
- */
-abstract class Piwik_Archive
-{
- /**
- * When saving DataTables in the DB, we sometimes replace the columns name by these IDs so we save up lots of bytes
- * Eg. INDEX_NB_UNIQ_VISITORS is an integer: 4 bytes, but 'nb_uniq_visitors' is 16 bytes at least
- * (in php it's actually even much more)
- *
- */
- 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;
-
- /**
- * Website Piwik_Site
- *
- * @var Piwik_Site
- */
- protected $site = null;
-
- /**
- * Stores the already built archives.
- * Act as a big caching array
- *
- * @var array of Piwik_Archive
- */
- static protected $alreadyBuilt = array();
-
- /**
- * Builds an Archive object or returns the same archive if previously built.
- *
- * @param string|int idSite integer, or comma separated list of integer
- * @param string|Piwik_Date $date 'YYYY-MM-DD' or magic keywords 'today' @see Piwik_Date::factory()
- * @param string $period 'week' 'day' etc.
- *
- * @return Piwik_Archive
- */
- static public function build($idSite, $period, $strDate )
- {
- if($idSite === 'all')
- {
- $sites = Piwik_SitesManager_API::getSitesIdWithAtLeastViewAccess();
- }
- else
- {
- $sites = Piwik_Site::getIdSitesFromIdSitesString($idSite);
- } -
- // idSite=1,3 or idSite=all
- if( count($sites) > 1 - || $idSite === 'all' )
- {
- require_once 'Archive/Array/IndexedBySite.php';
- $archive = new Piwik_Archive_Array_IndexedBySite($sites, $period, $strDate);
- }
- // if a period date string is detected: either 'last30', 'previous10' or 'YYYY-MM-DD,YYYY-MM-DD'
- elseif(is_string($strDate)
- && (
- ereg('^(last|previous){1}([0-9]*)$', $strDate, $regs)
- || ereg('^([0-9]{4}-[0-9]{1,2}-[0-9]{1,2}),([0-9]{4}-[0-9]{1,2}-[0-9]{1,2})$', $strDate, $regs)
- )
- )
- {
- $oSite = new Piwik_Site($idSite);
- require_once 'Archive/Array/IndexedByDate.php';
- $archive = new Piwik_Archive_Array_IndexedByDate($oSite, $period, $strDate);
- }
- // case we request a single archive
- else
- {
- if(is_string($strDate))
- {
- $oDate = Piwik_Date::factory($strDate);
- }
- else
- {
- $oDate = $strDate;
- }
- $date = $oDate->toString();
-
- if(isset(self::$alreadyBuilt[$idSite][$date][$period]))
- {
- return self::$alreadyBuilt[$idSite][$date][$period];
- }
-
- $oPeriod = Piwik_Period::factory($period, $oDate);
-
- $archive = new Piwik_Archive_Single;
- $archive->setPeriod($oPeriod);
- $archive->setSite(new Piwik_Site($idSite));
-
- self::$alreadyBuilt[$idSite][$date][$period] = $archive;
- }
-
- return $archive;
- }
-
- abstract public function prepareArchive();
-
- /**
- * Returns the value of the element $name from the current archive
- * The value to be returned is a numeric value and is stored in the archive_numeric_* tables
- *
- * @param string $name For example Referers_distinctKeywords
- * @return float|int|false False if no value with the given name
- */
- abstract public function getNumeric( $name );
-
- /**
- * Returns the value of the element $name from the current archive
- *
- * The value to be returned is a blob value and is stored in the archive_numeric_* tables
- *
- * It can return anything from strings, to serialized PHP arrays or PHP objects, etc.
- *
- * @param string $name For example Referers_distinctKeywords
- * @return mixed False if no value with the given name
- */
- abstract public function getBlob( $name );
-
- abstract public function getDataTableFromNumeric( $fields );
-
- /**
- * This method will build a dataTable from the blob value $name in the current archive.
- *
- * For example $name = 'Referers_searchEngineByKeyword' will return a Piwik_DataTable containing all the keywords
- * If a idSubTable is given, the method will return the subTable of $name
- *
- * @param string $name
- * @param int $idSubTable or null if requesting the parent table
- * @return Piwik_DataTable
- * @throws exception If the value cannot be found
- */
- abstract public function getDataTable( $name, $idSubTable = null );
-
- /**
- * Same as getDataTable() except that it will also load in memory
- * all the subtables for the DataTable $name.
- * You can then access the subtables by using the Piwik_DataTable_Manager getTable()
- *
- * @param string $name
- * @param int $idSubTable or null if requesting the parent table
- * @return Piwik_DataTable
- */
- abstract public function getDataTableExpanded($name, $idSubTable = null);
-
- /**
- * Sets the site
- *
- * @param Piwik_Site $site
- */
- public function setSite( Piwik_Site $site )
- {
- $this->site = $site;
- }
-
- /**
- * Gets the site
- *
- * @param Piwik_Site $site
- */
- public function getSite()
- {
- return $this->site;
- }
-
- /**
- * Returns the Id site associated with this archive
- *
- * @return int
- */
- public function getIdSite()
- {
- return $this->site->getId();
- }
-
-}
-
-
-
-
-
diff --git a/modules/Archive/Array.php b/modules/Archive/Array.php deleted file mode 100644 index 479cbd39ed..0000000000 --- a/modules/Archive/Array.php +++ /dev/null @@ -1,161 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id: Request.php 380 2008-03-17 14:59:24Z matt $ - * - * - * @package Piwik_Archive - */ - -require_once "DataTable/Simple.php"; -require_once "DataTable/Array.php"; -/** - * This class is used to store multiple archives, when the user requests a period's archive. - * - */ -abstract class Piwik_Archive_Array extends Piwik_Archive -{ - /** - * This array contains one Piwik_Archive per entry in the period - * - * @var array - */ - protected $archives = array(); - - abstract protected function getIndexName(); - abstract protected function getDataTableLabelValue( $archive ); - - public function prepareArchive() - { - foreach($this->archives as $archive) - { - $archive->prepareArchive(); - } - } - - /** - * Returns a newly created Piwik_DataTable_Array. - * - * @return Piwik_DataTable_Array - */ - protected function getNewDataTableArray() - { - $table = new Piwik_DataTable_Array; - $table->setKeyName($this->getIndexName()); - return $table; - } - - - - /** - * Adds metadata information to the Piwik_DataTable_Array - * using the information given by the Archive - * - * @param Piwik_DataTable_Array $table - * @param unknown_type $archive - */ - protected function loadMetadata(Piwik_DataTable_Array $table, $archive) - { - } - - /** - * Returns a DataTable_Array containing numeric values - * of the element $name from the archives in this Archive_Array. - * - * @param string $name Name of the mysql table field to load eg. Referers_distinctKeywords - * - * @return Piwik_DataTable_Array containing the requested numeric value for each Archive - */ - public function getNumeric( $name ) - { - $table = $this->getNewDataTableArray(); - - foreach($this->archives as $archive) - { - $numeric = $archive->getNumeric( $name ) ; - $subTable = new Piwik_DataTable_Simple(); - $subTable->loadFromArray( array( $numeric ) ); - $table->addTable($subTable, $this->getDataTableLabelValue($archive)); - - $this->loadMetadata($table, $archive); - } - - return $table; - } - - - /** - * Returns a DataTable_Array containing values - * of the element $name from the archives in this Archive_Array. - * - * The value to be returned are blob values (stored in the archive_numeric_* tables in the DB). * - * It can return anything from strings, to serialized PHP arrays or PHP objects, etc. - * - * @param string $name Name of the mysql table field to load eg. Referers_keywordBySearchEngine - * - * @return Piwik_DataTable_Array containing the requested blob values for each Archive - */ - public function getBlob( $name ) - { - $table = $this->getNewDataTableArray(); - - foreach($this->archives as $archive) - { - $blob = $archive->getBlob( $name ) ; - $subTable = new Piwik_DataTable_Simple(); - $subTable->loadFromArray( array('blob' => $blob)); - $table->addTable($subTable, $this->getDataTableLabelValue($archive)); - - $this->loadMetadata($table, $archive); - } - return $table; - } - - /** - * Given a BLOB field name (eg. 'Referers_searchEngineByKeyword'), it will return a Piwik_DataTable_Array - * which is an array of Piwik_DataTable, ordered by chronological order - * - * @param string $name Name of the mysql table field to load - * @param int $idSubTable optional idSubDataTable - * @return Piwik_DataTable_Array - * @throws exception If the value cannot be found - */ - public function getDataTable( $name, $idSubTable = null ) - { - $table = $this->getNewDataTableArray(); - foreach($this->archives as $archive) - { - $subTable = $archive->getDataTable( $name, $idSubTable ) ; - $table->addTable($subTable, $this->getDataTableLabelValue($archive)); - - $this->loadMetadata($table, $archive); - } - return $table; - } - - - /** - * Same as getDataTable() except that it will also load in memory - * all the subtables for the DataTable $name. - * You can then access the subtables by using the Piwik_DataTable_Manager::getInstance()->getTable($idSubTable); - * - * @param string $name Name of the mysql table field to load - * @param int $idSubTable optional idSubDataTable - * @return Piwik_DataTable_Array - */ - public function getDataTableExpanded($name, $idSubTable = null) - { - $table = $this->getNewDataTableArray(); - foreach($this->archives as $archive) - { - $subTable = $archive->getDataTableExpanded( $name, $idSubTable ) ; - $table->addTable($subTable, $this->getDataTableLabelValue($archive)); - - $this->loadMetadata($table, $archive); - } - return $table; - } -} diff --git a/modules/Archive/Array/IndexedByDate.php b/modules/Archive/Array/IndexedByDate.php deleted file mode 100644 index 87e57491d2..0000000000 --- a/modules/Archive/Array/IndexedByDate.php +++ /dev/null @@ -1,122 +0,0 @@ -<?php -require_once "Archive/Array.php"; - -class Piwik_Archive_Array_IndexedByDate extends Piwik_Archive_Array { - - /** - * Builds an array of Piwik_Archive of a given date range - * - * @param Piwik_Site $oSite - * @param string $strPeriod eg. 'day' 'week' etc. - * @param string $strDate A date range, eg. 'last10', 'previous5' or 'YYYY-MM-DD,YYYY-MM-DD' - */ - function __construct(Piwik_Site $oSite, $strPeriod, $strDate) - { - $rangePeriod = new Piwik_Period_Range($strPeriod, $strDate); - foreach($rangePeriod->getSubperiods() as $subPeriod) - { - $startDate = $subPeriod->getDateStart(); - $archive = Piwik_Archive::build($oSite->getId(), $strPeriod, $startDate ); - $archive->prepareArchive(); - $timestamp = $archive->getTimestampStartDate(); - $this->archives[$timestamp] = $archive; - } - ksort( $this->archives ); - } - - protected function getIndexName() - { - return 'date'; - } - - protected function loadMetadata(Piwik_DataTable_Array $table, $archive) - { - $table->metadata[$archive->getPrettyDate()] = array( - 'timestamp' => $archive->getTimestampStartDate(), - 'site' => $archive->getSite(), - ); - } - protected function getDataTableLabelValue( $archive ) - { - return $archive->getPrettyDate(); - } - - /** - * Given a list of fields defining numeric values, it will return a Piwik_DataTable_Array - * which is an array of Piwik_DataTable_Simple, ordered by chronological order - * - * @param array|string $fields array( fieldName1, fieldName2, ...) Names of the mysql table fields to load - * @return Piwik_DataTable_Array - */ - public function getDataTableFromNumeric( $fields ) - { - if(!is_array($fields)) - { - $fields = array($fields); - } - - $inName = "'" . implode("', '",$fields) . "'"; - - // we select in different shots - // one per distinct table (case we select last 300 days, maybe we will select from 10 different tables) - $queries = array(); - foreach($this->archives as $archive) - { - if(!$archive->isThereSomeVisits) - { - continue; - } - - $table = $archive->archiveProcessing->getTableArchiveNumericName(); - - // for every query store IDs - $queries[$table][] = $archive->getIdArchive(); - } - // we select the requested value - $db = Zend_Registry::get('db'); - - // date => array( 'field1' =>X, 'field2'=>Y) - // date2 => array( 'field1' =>X2, 'field2'=>Y2) - - $arrayValues = array(); - foreach($queries as $table => $aIds) - { - $inIds = implode(', ', $aIds); - $sql = "SELECT value, name, idarchive, UNIX_TIMESTAMP(date1) as timestamp - FROM $table - WHERE idarchive IN ( $inIds ) - AND name IN ( $inName )"; - - $values = $db->fetchAll($sql); - - foreach($values as $value) - { - $arrayValues[$value['timestamp']][$value['name']] = $value['value']; - } - } - - $contentArray = array(); - // we add empty tables so that every requested date has an entry, even if there is nothing - // example: <result date="2007-01-01" /> - foreach($this->archives as $timestamp => $archive) - { - $strDate = $this->archives[$timestamp]->getPrettyDate(); - $contentArray[$timestamp]['table'] = new Piwik_DataTable_Simple(); - $contentArray[$timestamp]['prettyDate'] = $strDate; - } - - foreach($arrayValues as $timestamp => $aNameValues) - { - $contentArray[$timestamp]['table']->loadFromArray($aNameValues); - } - ksort( $contentArray ); - - $tableArray = $this->getNewDataTableArray(); - foreach($contentArray as $timestamp => $aData) - { - $tableArray->addTable($aData['table'], $aData['prettyDate']); - $this->loadMetadata($tableArray, $this->archives[$timestamp]); - } - return $tableArray; - } -}
\ No newline at end of file diff --git a/modules/Archive/Array/IndexedBySite.php b/modules/Archive/Array/IndexedBySite.php deleted file mode 100644 index 8d1f984809..0000000000 --- a/modules/Archive/Array/IndexedBySite.php +++ /dev/null @@ -1,98 +0,0 @@ -<?php -require_once "Archive/Array.php"; - -class Piwik_Archive_Array_IndexedBySite extends Piwik_Archive_Array { - - /** - * - * @param Piwik_Site $oSite - * @param string $strPeriod eg. 'day' 'week' etc. - * @param string $strDate A date range, eg. 'last10', 'previous5' or 'YYYY-MM-DD,YYYY-MM-DD' - */ - function __construct($sites, $strPeriod, $strDate) - { - foreach($sites as $idSite) - { - $archive = Piwik_Archive::build($idSite, $strPeriod, $strDate ); - $archive->setSite(new Piwik_Site($idSite)); - $archive->prepareArchive(); - $this->archives[$idSite] = $archive; - } - ksort( $this->archives ); - } - - protected function getIndexName() - { - return 'idSite'; - } - - protected function getDataTableLabelValue( $archive ) - { - return $archive->getIdSite(); - } - - /** - * Given a list of fields defining numeric values, it will return a Piwik_DataTable_Array - * which is an array of Piwik_DataTable_Simple, ordered by chronological order - * - * @param array|string $fields array( fieldName1, fieldName2, ...) Names of the mysql table fields to load - * @return Piwik_DataTable_Array - */ - public function getDataTableFromNumeric( $fields ) - { - if(!is_array($fields)) - { - $fields = array($fields); - } - $inName = "'" . implode("', '",$fields) . "'"; - - $numericTable = null; - $aIds = array(); - foreach($this->archives as $archive) - { - if(is_null($numericTable)) - { - $numericTable = $archive->archiveProcessing->getTableArchiveNumericName(); - } - else if( $numericTable != $archive->archiveProcessing->getTableArchiveNumericName()) - { - throw new Exception("Piwik_Archive_Array_IndexedBySite::getDataTableFromNumeric() algorithm won't work if data is stored in different tables"); - } - $aIds[] = $archive->getIdArchive(); - } - - $inIds = implode(', ', $aIds); - $sql = "SELECT value, name, idarchive, idsite - FROM $numericTable - WHERE idarchive IN ( $inIds ) - AND name IN ( $inName )"; - $values = Zend_Registry::get('db')->fetchAll($sql); - - $arrayValues = array(); - foreach($values as $value) - { - $arrayValues[$value['idsite']][$value['name']] = $value['value']; - } - - // we add empty tables so that every requested date has an entry, even if there is nothing - // example: <result idSite="159" /> - $contentArray = array(); - foreach($this->archives as $idSite => $archive) - { - $contentArray[$idSite]['table'] = new Piwik_DataTable_Simple(); - } - - foreach($arrayValues as $idSite => $aNameValues) - { - $contentArray[$idSite]['table']->loadFromArray($aNameValues); - } - ksort( $contentArray ); - - $tableArray = $this->getNewDataTableArray(); - foreach($contentArray as $idSite => $aData) - { - $tableArray->addTable($aData['table'], $idSite); - } - return $tableArray; - } -}
\ No newline at end of file diff --git a/modules/Archive/Single.php b/modules/Archive/Single.php deleted file mode 100644 index be4fbde7e4..0000000000 --- a/modules/Archive/Single.php +++ /dev/null @@ -1,463 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id: Request.php 380 2008-03-17 14:59:24Z matt $ - * - * - * @package Piwik_Archive - */ - -/** - * This class is used to store the data of a single archive, - * for example the statistics for the 'day' '2008-02-21' for the website idSite '2' - * - */ -class Piwik_Archive_Single extends Piwik_Archive -{ - /** - * The Piwik_ArchiveProcessing object used to check that the archive is available - * and launch the processing if the archive was not yet processed - * - * @var Piwik_ArchiveProcessing - */ - public $archiveProcessing = null; - - /** - * @var bool Set to true if the archive has at least 1 visit - */ - public $isThereSomeVisits = false; - - /** - * Period of this Archive - * - * @var Piwik_Period - */ - protected $period = null; - - /** - * Set to true will activate numeric value caching for this archive. - * - * @var bool - */ - protected $cacheEnabledForNumeric = true; - - /** - * Array of cached numeric values, used to make requests faster - * when requesting the same value again and again - * - * @var array of numeric - */ - protected $numericCached = array(); - - /** - * Array of cached blob, used to make requests faster when requesting the same blob again and again - * - * @var array of mixed - */ - protected $blobCached = array(); - - /** - * idarchive of this Archive in the database - * - * @var int - */ - protected $idArchive = null; - - /** - * Flag set to true once the archive has been checked (when we make sure it is archived) - * - * @var bool - */ - protected $alreadyChecked = false; - - /** - * Returns the pretty date of this Archive, eg. 'Thursday 20th March 2008' - * - * @return string - */ - public function getPrettyDate() - { - return $this->period->getPrettyString(); - } - - /** - * Returns the idarchive of this Archive used to index this archive in the DB - * - * @return int - */ - public function getIdArchive() - { - if(is_null($this->idArchive)) - { - throw new Exception("idArchive is null"); - } - return $this->idArchive; - } - - /** - * Set the period - * - * @param Piwik_Period $period - */ - public function setPeriod( Piwik_Period $period ) - { - $this->period = $period; - } - - /** - * Returns the timestamp of the first date in the period for this Archive. - * This is used to sort archives by date when working on a Archive_Array - * - * @return int Unix timestamp - */ - public function getTimestampStartDate() - { - if(!is_null($this->archiveProcessing)) - { - return $this->archiveProcessing->getTimestampStartDate(); - } - - return $this->period->getDateStart()->getTimestamp(); - } - - /** - * Prepares the archive. Gets the idarchive from the ArchiveProcessing. - * - * This will possibly launch the archiving process if the archive was not available. - * - * @return void - */ - public function prepareArchive() - { - if(!$this->alreadyChecked) - { - $this->isThereSomeVisits = false; - $this->alreadyChecked = true; - - // if the END of the period is BEFORE the website creation date - // we already know there are no stats for this period - // we add one day to make sure we don't miss the day of the website creation - if( $this->period->getDateEnd()->addDay(2)->isEarlier( $this->site->getCreationDate() ) ) - { - return; - } - - // if the starting date is in the future we know there is no visit - if( $this->period->getDateStart()->subDay(1)->isLater( Piwik_Date::today() ) ) - { - return; - } - - // we make sure the archive is available for the given date - $periodLabel = $this->period->getLabel(); - $archiveProcessing = Piwik_ArchiveProcessing::factory($periodLabel); - $archiveProcessing->setSite($this->site); - $archiveProcessing->setPeriod($this->period); - - $idArchive = $archiveProcessing->loadArchive(); - $this->isThereSomeVisits = $archiveProcessing->isThereSomeVisits; - - $this->archiveProcessing = $archiveProcessing; - - $this->idArchive = $idArchive; - $this->alreadyChecked = true; - } - } - - /** - * Returns a value from the current archive with the name = $name - * Method used by getNumeric or getBlob - * - * @param string $name - * @param string $typeValue numeric|blob - * @return mixed|false if no result - */ - protected function get( $name, $typeValue = 'numeric' ) - { - // values previously "get" and now cached - if($typeValue == 'numeric' - && $this->cacheEnabledForNumeric - && isset($this->numericCached[$name]) - ) - { - return $this->numericCached[$name]; - } - - // During archiving we prefetch the blobs recursively - // and we get them faster from memory after - if($typeValue == 'blob' - && isset($this->blobCached[$name])) - { - return $this->blobCached[$name]; - } - - $this->prepareArchive(); - - if($name == 'idarchive') - { - return $this->idArchive; - } - -// Piwik::log("-- get '$name'"); - - if(!$this->isThereSomeVisits) - { - return false; - } - - // select the table to use depending on the type of the data requested - switch($typeValue) - { - case 'blob': - $table = $this->archiveProcessing->getTableArchiveBlobName(); - break; - - case 'numeric': - default: - $table = $this->archiveProcessing->getTableArchiveNumericName(); - break; - } - - // we select the requested value - $db = Zend_Registry::get('db'); - $value = $db->fetchOne("SELECT value - FROM $table - WHERE idarchive = ? - AND name = ?", - array( $this->idArchive , $name) - ); - - // no result, returns false - if($value === false) - { - if($typeValue == 'numeric' - && $this->cacheEnabledForNumeric) - { - // we cache the results - $this->numericCached[$name] = false; - } - return $value; - } - - // uncompress when selecting from the BLOB table - if($typeValue == 'blob') - { - $value = gzuncompress($value); - } - - if($typeValue == 'numeric' - && $this->cacheEnabledForNumeric) - { - // we cache the results - $this->numericCached[$name] = $value; - } - return $value; - } - - - /** - * This method loads in memory all the subtables for the main table called $name. - * You have to give it the parent table $dataTableToLoad so we can lookup the sub tables ids to load. - * - * If $addMetadataSubtableId set to true, it will add for each row a 'metadata' called 'databaseSubtableId' - * containing the child ID of the subtable associated to this row. - * - * @param string $name - * @param Piwik_DataTable $dataTableToLoad - * @param bool $addMetadataSubtableId - * - * @return void - */ - public function loadSubDataTables($name, Piwik_DataTable $dataTableToLoad, $addMetadataSubtableId = false) - { - // we have to recursively load all the subtables associated to this table's rows - // and update the subtableID so that it matches the newly instanciated table - foreach($dataTableToLoad->getRows() as $row) - { - $subTableID = $row->getIdSubDataTable(); - - if($subTableID !== null) - { - $subDataTableLoaded = $this->getDataTable($name, $subTableID); - - $this->loadSubDataTables($name, $subDataTableLoaded); - - // we edit the subtable ID so that it matches the newly table created in memory - // NB: - // we dont do that in the case we are displaying the table expanded. - // in this case we want the user to see the REAL dataId in the database - if($addMetadataSubtableId) - { - $row->addMetadata('databaseSubtableId', $row->getIdSubDataTable()); - } - $row->setSubtable( $subDataTableLoaded ); - } - } - } - - - /** - * Free the blob cache memory array - * - * @return void - */ - public function freeBlob( $name ) - { - // we delete the blob - $this->blobCached = null; - $this->blobCached = array(); - } - - /** - * Fetches all blob fields name_* at once for the current archive for performance reasons. - * - * @return void - */ - public function preFetchBlob( $name ) - { - if(!$this->isThereSomeVisits) - { - return false; - } - - $tableBlob = $this->archiveProcessing->getTableArchiveBlobName(); - - // we select the requested value - $db = Zend_Registry::get('db'); - $query = $db->query("SELECT value, name - FROM $tableBlob - WHERE idarchive = ? - AND name LIKE '$name%'", - array( $this->idArchive ) - ); - - while($row = $query->fetch()) - { - $value = $row['value']; - $name = $row['name']; - - $this->blobCached[$name] = gzuncompress($value); - } - } - - /** - * Returns a numeric value from this Archive, with the name '$name' - * - * @param string $name - * @return int|float - */ - public function getNumeric( $name ) - { - // we cast the result as float because returns false when no visitors - return (float)$this->get($name, 'numeric'); - } - - - /** - * Returns a blob value from this Archive, with the name '$name' - * Blob values are all values except int and float. - * - * @param string $name - * @return mixed - */ - public function getBlob( $name ) - { - return $this->get($name, 'blob'); - } - - /** - * Given a list of fields defining numeric values, it will return a Piwik_DataTable_Simple - * containing one row per field name. - * - * For example $fields = array( 'max_actions', - * 'nb_uniq_visitors', - * 'nb_visits', - * 'nb_actions', - * 'sum_visit_length', - * 'bounce_count', - * ); - * - * @param string|array $fields Name or array of names of Archive fields - * - * @return Piwik_DataTable_Simple - */ - public function getDataTableFromNumeric( $fields ) - { - require_once "DataTable/Simple.php"; - if(!is_array($fields)) - { - $fields = array($fields); - } - - $values = array(); - foreach($fields as $field) - { - $values[$field] = $this->getNumeric($field); - } - - $table = new Piwik_DataTable_Simple; - $table->loadFromArray($values); - return $table; - } - - /** - * Returns a DataTable that has the name '$name' from the current Archive. - * If $idSubTable is specified, returns the subDataTable called '$name_$idSubTable' - * - * @param string $name - * @param int $idSubTable optional id SubDataTable - * @return Piwik_DataTable - */ - public function getDataTable( $name, $idSubTable = null ) - { - if(!is_null($idSubTable)) - { - $name .= "_$idSubTable"; - } - - $data = $this->get($name, 'blob'); - - $table = new Piwik_DataTable; - - if($data !== false) - { - $table->loadFromSerialized($data); - } - - if($data === false - && $idSubTable !== null) - { - throw new Exception("You are requesting a precise subTable but there is not such data in the Archive."); - } - - return $table; - } - - /** - * Returns a DataTable that has the name '$name' from the current Archive. - * Also loads in memory all subDataTable for this DataTable. - * - * For example, if $name = 'Referers_keywordBySearchEngine' it will load all DataTable - * named 'Referers_keywordBySearchEngine_*' and they will be set as subDataTable to the - * rows. You can then go through the rows - * $rows = DataTable->getRows(); - * and for each row request the subDataTable (in this case the DataTable of the keywords for each search engines) - * $idSubTable = $row->getIdSubDataTable(); - * $subTable = Piwik_DataTable_Manager::getInstance()->getTable($idSubTable); - * - * @param string $name - * @param int $idSubTable Optional subDataTable to load instead of loading the parent DataTable - * @return Piwik_DataTable - */ - public function getDataTableExpanded($name, $idSubTable = null) - { - $this->preFetchBlob($name); - $dataTableToLoad = $this->getDataTable($name, $idSubTable); - $this->loadSubDataTables($name, $dataTableToLoad, $addMetadataSubtableId = true); - return $dataTableToLoad; - } -} -?>
\ No newline at end of file diff --git a/modules/ArchiveProcessing.php b/modules/ArchiveProcessing.php deleted file mode 100644 index caa31299de..0000000000 --- a/modules/ArchiveProcessing.php +++ /dev/null @@ -1,570 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_ArchiveProcessing - */ - -require_once 'TablePartitioning.php'; -require_once 'ArchiveProcessing/Record.php'; -require_once 'DataTable.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. - * - * The ArchiveProcessing class is used by the Archive object to make sure the given Archive is processed and available in the DB. - * - * A record in the Database for a given report is defined by - * - idarchive = unique ID that is associated to all the data of this archive (idsite+period+date) - * - idsite = the ID of the website - * - date1 = starting day of the period - * - date2 = ending day of the period - * - period = integer that defines the period (day/week/etc.). @see period::getId() - * - 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 - */ -abstract class Piwik_ArchiveProcessing -{ - /** - * Flag stored at the end of the archiving - * - * @var int - */ - const DONE_OK = 1; - - /** - * Flag stored at the start of the archiving - * When requesting an Archive, we make sure that non-finished archive are not considered valid - * - * @var int - */ - const DONE_ERROR = 2; - - /** - * Idarchive in the DB for the requested archive - * - * @var int - */ - protected $idArchive; - - /** - * Period id @see Piwik_Period::getId() - * - * @var int - */ - protected $periodId; - - /** - * Timestamp for the first date of the period - * - * @var int unix timestamp - */ - protected $timestampDateStart = null; - - /** - * Starting date of the archive - * - * @var Piwik_Date - */ - protected $dateStart; - - /** - * Ending date of the archive - * - * @var Piwik_Date - */ - protected $dateEnd; - - /** - * Object used to generate (depending on the $dateStart) the name of the DB table to use to store numeric values - * - * @var Piwik_TablePartitioning - */ - protected $tableArchiveNumeric; - - /** - * Object used to generate (depending on the $dateStart) the name of the DB table to use to store numeric values - * - * @var Piwik_TablePartitioning - */ - protected $tableArchiveBlob; - - /** - * Maximum timestamp above which a given archive is considered out of date - * - * @var int - */ - protected $maxTimestampArchive; - - /** - * Id of the current site - * Can be accessed by plugins (that is why it's public) - * - * @var int - */ - public $idsite = null; - - /** - * Period of the current archive - * Can be accessed by plugins (that is why it's public) - * - * @var Piwik_Period - */ - public $period = null; - - /** - * Site of the current archive - * Can be accessed by plugins (that is why it's public) - * - * @var Piwik_Site - */ - public $site = null; - - /** - * Starting date @see Piwik_Date::toString() - * - * @var string - */ - public $strDateStart; - - /** - * Ending date @see Piwik_Date::toString() - * - * @var string - */ - public $strDateEnd; - - /** - * Name of the DB table _log_visit - * - * @var string - */ - public $logTable; - - /** - * Name of the DB table _log_link_visit_action - * - * @var string - */ - public $logVisitActionTable; - - /** - * Name of the DB table _log_action - * - * @var string - */ - public $logActionTable; - - /** - * When set to true, we always archive, even if the archive is already available. - * You can change this settings automatically in the config/global.ini.php always_archive_data under the [Debug] section - * - * @var bool - */ - protected $debugAlwaysArchive = false; - - /** - * Builds the archive processing object, - * Reads some configuration value from the config file - * - */ - public function __construct() - { - $this->debugAlwaysArchive = Zend_Registry::get('config')->Debug->always_archive_data; - } - - /** - * Returns the Piwik_ArchiveProcessing_Day or Piwik_ArchiveProcessing_Period object - * depending on $name period string - * - * @param string $name day|week|month|year - * @return Piwik_ArchiveProcessing Piwik_ArchiveProcessing_Day|Piwik_ArchiveProcessing_Period - */ - static function factory($name ) - { - switch($name) - { - case 'day': - require_once 'ArchiveProcessing/Day.php'; - $process = new Piwik_ArchiveProcessing_Day; - break; - - case 'week': - case 'month': - case 'year': - require_once 'ArchiveProcessing/Period.php'; - $process = new Piwik_ArchiveProcessing_Period; - break; - - default: - throw new Exception("Unknown period specified $name"); - break; - } - return $process; - } - - /** - * Inits the object - * - * @return void - */ - protected function loadArchiveProperties() - { - $this->idsite = $this->site->getId(); - - $this->periodId = $this->period->getId(); - - $this->dateStart = $this->period->getDateStart(); - $this->dateEnd = $this->period->getDateEnd(); - - $this->tableArchiveNumeric = new Piwik_TablePartitioning_Monthly('archive_numeric'); - $this->tableArchiveNumeric->setTimestamp($this->dateStart->get()); - $this->tableArchiveBlob = new Piwik_TablePartitioning_Monthly('archive_blob'); - $this->tableArchiveBlob->setTimestamp($this->dateStart->get()); - - $this->strDateStart = $this->dateStart->toString(); - $this->strDateEnd = $this->dateEnd->toString(); - - // if the current archive is a DAY and if it's today, - // we set this maxTimestampArchive that defines the lifetime value of today's archive - $this->maxTimestampArchive = 0; - if( $this->period->getNumberOfSubperiods() == 0 - && $this->period->toString() == date("Y-m-d") - ) - { - //TODO this TIMESTAMP should be a mysql NOW()!!!! - $this->maxTimestampArchive = time() - Zend_Registry::get('config')->General->time_before_archive_considered_outdated; - } - // either - // - if the period we're looking for is finished, we look for a ts_archived that - // is greater than the last day of the archive - // - if the period we're looking for is not finished, we look for a recent enough archive - // recent enough means maxTimestampArchive = 00:00:01 this morning - else - { - if($this->period->isFinished()) - { - $this->maxTimestampArchive = $this->period->getDateEnd()->setTime('00:00:00')->addDay(1)->getTimestamp(); - } - else - { - $this->maxTimestampArchive = Piwik_Date::today()->getTimestamp(); - } - } - } - - /** - * This method returns the idArchive ; if necessary, it triggers the archiving process. - * - * If the archive was not processed yet, it will launch the archiving process. - * If the current archive needs sub-archives (eg. a month archive needs all the days archive) - * it will recursively launch the archiving (using this loadArchive() on the sub-periods) - * - * @return int The idarchive of the archive - */ - public function loadArchive() - { - $this->loadArchiveProperties(); - $this->idArchive = $this->isArchived(); - - if($this->idArchive === false - && $this->isArchivingDisabled()) - { - $this->isThereSomeVisits = false; - } - elseif($this->idArchive === false - || $this->debugAlwaysArchive) - { - $this->launchArchiving(); - } - else - { - $this->isThereSomeVisits = true; - } - - return $this->idArchive; - } - - /** - * @see loadArchive() - * - */ - protected function launchArchiving() - { - $this->initCompute(); - $this->compute(); - $this->postCompute(); - // we execute again the isArchived that does some initialization work - $this->idArchive = $this->isArchived(); - } - - /** - * This methods reads the subperiods if necessary, - * and computes the archive of the current period. - */ - abstract protected function compute(); - - /** - * Init the object before launching the real archive processing - * - * @return void - */ - protected function initCompute() - { - $this->loadNextIdarchive(); - - $record = new Piwik_ArchiveProcessing_Record_Numeric('done', Piwik_ArchiveProcessing::DONE_ERROR); - $this->insertRecord($record); - $record->delete(); - - $this->logTable = Piwik::prefixTable('log_visit'); - $this->logVisitActionTable = Piwik::prefixTable('log_link_visit_action'); - $this->logActionTable = Piwik::prefixTable('log_action'); - } - - /** - * Post processing called at the end of the main archive processing. - * Makes sure the new archive is marked as "successful" in the DB - * - * We also try to delete some stuff from memory but really there is still a lot... - * - * @return void - */ - protected function postCompute() - { - // delete the first done = ERROR - Zend_Registry::get('db')->query(" - DELETE FROM ".$this->tableArchiveNumeric->getTableName()." - WHERE idarchive = ? AND name = 'done'", - array($this->idArchive) - ); - - $record = new Piwik_ArchiveProcessing_Record_Numeric('done', Piwik_ArchiveProcessing::DONE_OK); - - // save in the database the records - $records = Piwik_ArchiveProcessing_Record_Manager::getInstance()->getRecords(); - - foreach($records as $record) - { - $this->insertRecord( $record); - } - - // delete the records from the global manager - foreach($records as $record) - { - $record->delete(); - } - unset($records); - - // we delete all tables from the table register - Piwik_ArchiveProcessing_Record_Manager::getInstance()->deleteAll(); - } - - /** - * Returns the name of the numeric table where the archive numeric values are stored - * - * @return string - */ - public function getTableArchiveNumericName() - { - return $this->tableArchiveNumeric->getTableName(); - } - - /** - * Returns the name of the blob table where the archive blob values are stored - * - * @return string - */ - public function getTableArchiveBlobName() - { - return $this->tableArchiveBlob->getTableName(); - } - - /** - * Set the period - * - * @param Piwik_Period $period - */ - public function setPeriod( Piwik_Period $period ) - { - $this->period = $period; - } - - /** - * Set the site - * - * @param Piwik_Site $site - */ - public function setSite( Piwik_Site $site ) - { - $this->site = $site; - } - - /** - * Returns the timestamp of the first date of the period - * - * @return int - */ - public function getTimestampStartDate() - { - // case when archive processing is in the past or the future, the starting date has not been set or processed yet - if(is_null($this->timestampDateStart)) - { - return Piwik_Date::factory($this->strDateStart)->getTimestamp(); - } - return $this->timestampDateStart; - } - - /** - * Returns the idArchive we will use for the current archive - * - * @return int IdArchive to use when saving the current Archive - */ - protected function loadNextIdarchive() - { - $db = Zend_Registry::get('db'); - $id = $db->fetchOne("SELECT max(idarchive) FROM ".$this->tableArchiveNumeric->getTableName()); - if(empty($id)) - { - $id = 0; - } - $this->idArchive = $id + 1; - - } - - /** - * Inserts a record in the right table (either NUMERIC or BLOB) - * - * @param Piwik_ArchiveProcessing_Record $record - */ - protected function insertRecord($record) - { - // table to use to save the data - if(Piwik::isNumeric($record->value)) - { - $table = $this->tableArchiveNumeric; - } - else - { - $table = $this->tableArchiveBlob; - } - - $query = "INSERT INTO ".$table->getTableName()." (idarchive, idsite, date1, date2, period, ts_archived, name, value) - VALUES (?,?,?,?,?,?,?,?)"; - Zend_Registry::get('db')->query($query, - array( $this->idArchive, - $this->idsite, - $this->strDateStart, - $this->strDateEnd, - $this->periodId, - date("Y-m-d H:i:s"), - $record->name, - $record->value, - ) - ); - } - - /** - * Returns the idArchive if the archive is available in the database. - * Returns false if the archive needs to be computed. - * - * An archive is available if - * - for today, the archive was computed less than maxTimestampArchive seconds ago - * - for any other day, if the archive was computed once this day was finished - * - for other periods, if the archive was computed once the period was finished - * - * @return int|false - */ - protected function isArchived() - { - $bindSQL = array( $this->idsite, - $this->strDateStart, - $this->strDateEnd, - $this->periodId, - ); - $timeStampWhere = " AND UNIX_TIMESTAMP(ts_archived) >= ? "; - $bindSQL[] = $this->maxTimestampArchive; - - $sqlQuery = " SELECT idarchive, value, name, UNIX_TIMESTAMP(date1) as timestamp - FROM ".$this->tableArchiveNumeric->getTableName()." - WHERE idsite = ? - AND date1 = ? - AND date2 = ? - AND period = ? - AND ( (name = 'done' AND value = ".Piwik_ArchiveProcessing::DONE_OK.") - OR name = 'nb_visits') - $timeStampWhere - ORDER BY ts_archived DESC"; - - $results = Zend_Registry::get('db')->fetchAll($sqlQuery, $bindSQL ); - if(empty($results)) - { - return false; - } - - $idarchive = false; - // we look for the more recent idarchive - foreach($results as $result) - { - if($result['name'] == 'done') - { - $idarchive = $result['idarchive']; - $this->timestampDateStart = $result['timestamp']; - break; - } - } - - // case when we have a nb_visits entry in the archive, but the process is not finished yet or failed to finish - // therefore we don't have the done=OK - if($idarchive === false) - { - return false; - } - - // we look for the nb_visits result for this more recent archive - foreach($results as $result) - { - if($result['name'] == 'nb_visits' - && $result['idarchive'] == $idarchive) - { - $this->isThereSomeVisits = ($result['value'] != 0); - break; - } - } - return $idarchive; - } - - /** - * Returns true if, for some reasons, triggering the archiving is disabled. - * - * @return bool - */ - protected function isArchivingDisabled() - { - static $archivingIsDisabled = null; - - if(is_null($archivingIsDisabled)) - { - $archivingIsDisabled = false; - - $enableBrowserArchivingTriggering = (bool)Zend_Registry::get('config')->General->enable_browser_archiving_triggering; - if($enableBrowserArchivingTriggering == false) - { - if( !Piwik::isPhpCliMode()) - { - $archivingIsDisabled = true; - } - } - } - - return $archivingIsDisabled; - } -} diff --git a/modules/ArchiveProcessing/Day.php b/modules/ArchiveProcessing/Day.php deleted file mode 100644 index 231d13d2bd..0000000000 --- a/modules/ArchiveProcessing/Day.php +++ /dev/null @@ -1,348 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_ArchiveProcessing - */ - - -/** - * Handles the archiving process for a day. - * The class provides generic methods to manipulate data from the DB, easily create Piwik_DataTable objects. - * - * All the logic of the archiving is done inside the plugins listening to the event 'ArchiveProcessing_Day.compute' - * - * @package Piwik_ArchiveProcessing - * - */ -class Piwik_ArchiveProcessing_Day extends Piwik_ArchiveProcessing -{ - /** - * If the archive has at least 1 visit, this is set to true. - * - * @var bool - */ - public $isThereSomeVisits = false; - - /** - * Constructor - */ - function __construct() - { - parent::__construct(); - $this->db = Zend_Registry::get('db'); - } - - /** - * Main method to process logs for a day. The only logic done here is computing the number of visits, actions, etc. - * All the other reports are computed inside plugins listening to the event 'ArchiveProcessing_Day.compute'. - * See some of the plugins for an example eg. 'Provider' - * - * @return void - */ - protected function compute() - { - $query = "SELECT count(distinct visitor_idcookie) as nb_uniq_visitors, - count(*) as nb_visits, - sum(visit_total_actions) as nb_actions, - max(visit_total_actions) as max_actions, - sum(visit_total_time) as sum_visit_length, - sum(case visit_total_actions when 1 then 1 else 0 end) as bounce_count - FROM ".$this->logTable." - WHERE visit_server_date = ? - AND idsite = ? - GROUP BY visit_server_date - ORDER BY NULL - "; - $row = $this->db->fetchRow($query, array($this->strDateStart,$this->idsite ) ); - - if($row === false) - { - return; - } - $this->isThereSomeVisits = true; - - foreach($row as $name => $value) - { - $record = new Piwik_ArchiveProcessing_Record_Numeric($name, $value); - } - - Piwik_PostEvent('ArchiveProcessing_Day.compute', $this); - } - - /** - * Called at the end of the archiving process. - * Does some cleaning job in the database. - * - * @return void - */ - protected function postCompute() - { - parent::postCompute(); - - // we delete out of date records - // = archives that for day N computed on day N (means they are only partial) - $blobTable = $this->tableArchiveBlob->getTableName(); - $numericTable = $this->tableArchiveNumeric->getTableName(); - - $query = " DELETE - FROM %s - WHERE period = ? - AND date1 = DATE(ts_archived) - AND DATE(ts_archived) <> CURRENT_DATE() - "; - - Zend_Registry::get('db')->query(sprintf($query, $blobTable), $this->periodId); - Zend_Registry::get('db')->query(sprintf($query, $numericTable), $this->periodId); - } - - /** - * Helper function that returns a DataTable containing the $select fields / value pairs. - * IMPORTANT: The $select must return only one row!! - * - * Example $select = "count(distinct( config_os )) as countDistinctOs, - * sum( config_flash ) / count(distinct(idvisit)) as percentFlash " - * $labelCount = "test_column_name" - * will return a dataTable that looks like - * label test_column_name - * CountDistinctOs 9 - * PercentFlash 0.5676 - * - * - * @param string $select - * @param string $labelCount - * @return Piwik_DataTable - */ - public function getSimpleDataTableFromSelect($select, $labelCount) - { - $query = "SELECT $select - FROM ".$this->logTable." - WHERE visit_server_date = ? - AND idsite = ?"; - $data = $this->db->fetchRow($query, array( $this->strDateStart, $this->idsite )); - - foreach($data as $label => &$count) - { - $count = array($labelCount => $count); - } - $table = new Piwik_DataTable; - $table->loadFromArrayLabelIsKey($data); - return $table; - } - - /** - * Helper function that returns common statistics for a given database field distinct values. - * - * The statistics returned are: - * - number of unique visitors - * - number of visits - * - number of actions - * - maximum number of action for a visit - * - sum of the visits' length in sec - * - count of bouncing visits (visits with one page view) - * - * For example if $label = 'config_os' it will return the statistics for every distinct Operating systems - * The returned DataTable will have a row per distinct operating systems, - * and a column per stat (nb of visits, max actions, etc) - * - * label nb_uniq_visitors nb_visits nb_actions max_actions sum_visit_length bounce_count - * Linux 27 66 66 1 660 66 - * Windows XP 12 39 39 1 390 39 - * Mac OS 15 36 36 1 360 36 - * - * @param string $label Table log_visit field name to be use to compute common stats - * @return Piwik_DataTable - */ - public function getDataTableInterestForLabel( $label ) - { - $query = "SELECT $label as label, - count(distinct visitor_idcookie) as nb_uniq_visitors, - count(*) as nb_visits, - sum(visit_total_actions) as nb_actions, - max(visit_total_actions) as max_actions, - sum(visit_total_time) as sum_visit_length, - sum(case visit_total_actions when 1 then 1 else 0 end) as bounce_count - FROM ".$this->logTable." - WHERE visit_server_date = ? - AND idsite = ? - GROUP BY label"; - - $query = $this->db->query($query, array( $this->strDateStart, $this->idsite ) ); - - $interest = array(); - while($rowBefore = $query->fetch()) - { - $row = array( - Piwik_Archive::INDEX_NB_UNIQ_VISITORS => $rowBefore['nb_uniq_visitors'], - Piwik_Archive::INDEX_NB_VISITS => $rowBefore['nb_visits'], - Piwik_Archive::INDEX_NB_ACTIONS => $rowBefore['nb_actions'], - Piwik_Archive::INDEX_MAX_ACTIONS => $rowBefore['max_actions'], - Piwik_Archive::INDEX_SUM_VISIT_LENGTH => $rowBefore['sum_visit_length'], - Piwik_Archive::INDEX_BOUNCE_COUNT => $rowBefore['bounce_count'], - 'label' => $rowBefore['label'] - ); - - if(!isset($interest[$row['label']])) $interest[$row['label']]= $this->getNewInterestRow(); - $this->updateInterestStats( $row, $interest[$row['label']]); - } - - $table = new Piwik_DataTable; - $table->loadFromArrayLabelIsKey($interest); - return $table; - } - - /** - * Generates a dataTable given a multidimensional PHP array that associates LABELS to Piwik_DataTableRows - * This is used for the "Actions" DataTable, where a line is the aggregate of all the subtables - * Example: the category /blog has 3 visits because it has /blog/index (2 visits) + /blog/about (1 visit) - * - * @param array $table - * @return Piwik_DataTable - */ - static public function generateDataTable( $table ) - { - $dataTableToReturn = new Piwik_DataTable; - - foreach($table as $label => $maybeDatatableRow) - { - // case the aInfo is a subtable-like array - // it means that we have to go recursively and process it - // then we build the row that is an aggregate of all the children - // and we associate this row to the subtable - if( !($maybeDatatableRow instanceof Piwik_DataTable_Row) ) - { - $subTable = self::generateDataTable($maybeDatatableRow); - $row = new Piwik_DataTable_Row_DataTableSummary( $subTable ); - $row->addSubtable($subTable); - $row->setColumn('label', $label); - } - // if aInfo is a simple Row we build it - else - { - $row = $maybeDatatableRow; - } - - $dataTableToReturn->addRow($row); - } - - return $dataTableToReturn; - } - - /** - * Helper function that returns the serialized DataTable of the given PHP array. - * The array must have the format of Piwik_DataTable::loadFromArrayLabelIsKey() - * Example: array ( - * LABEL => array(col1 => X, col2 => Y), - * LABEL2 => array(col1 => X, col2 => Y), - * ) - * - * @param array $array at the given format - * @return array Array with one element: the serialized data table string - */ - public function getDataTableSerialized( $array ) - { - $table = new Piwik_DataTable; - $table->loadFromArrayLabelIsKey($array ); - $toReturn = $table->getSerialized(); - return $toReturn; - } - - - /** - * Helper function that returns the multiple serialized DataTable of the given PHP array. - * The DataTable here associates a subtable to every row of the level 0 array. - * This is used for example for search engines. Every search engine (level 0) has a subtable containing the - * keywords. - * - * The $arrayLevel0 must have the format - * Example: array ( - * LABEL => array(col1 => X, col2 => Y), - * LABEL2 => array(col1 => X, col2 => Y), - * ) - * - * The $subArrayLevel1ByKey must have the format - * Example: array( - * LABEL => #Piwik_DataTable_ForLABEL, - * LABEL2 => #Piwik_DataTable_ForLABEL2, - * ) - * - * - * @param array $arrayLevel0 - * @param array of Piwik_DataTable $subArrayLevel1ByKey - * @return array Array with N elements: the strings of the datatable serialized - */ - public function getDataTablesSerialized( $arrayLevel0, $subArrayLevel1ByKey, $maximumRowsInDataTableLevelZero = null, $maximumRowsInSubDataTable = null) - { - $tablesByLabel = array(); - - foreach($arrayLevel0 as $label => $aAllRowsForThisLabel) - { - $table = new Piwik_DataTable; - $table->loadFromArrayLabelIsKey($aAllRowsForThisLabel); - $tablesByLabel[$label] = $table; - } - $parentTableLevel0 = new Piwik_DataTable; - $parentTableLevel0->loadFromArrayLabelIsKey($subArrayLevel1ByKey, $tablesByLabel); - - $toReturn = $parentTableLevel0->getSerialized($maximumRowsInDataTableLevelZero, $maximumRowsInSubDataTable); - return $toReturn; - } - - /** - * Returns an empty row containing default values for the common stat - * - * @return array - */ - public function getNewInterestRow() - { - return array( Piwik_Archive::INDEX_NB_UNIQ_VISITORS => 0, - Piwik_Archive::INDEX_NB_VISITS => 0, - Piwik_Archive::INDEX_NB_ACTIONS => 0, - Piwik_Archive::INDEX_MAX_ACTIONS => 0, - Piwik_Archive::INDEX_SUM_VISIT_LENGTH => 0, - Piwik_Archive::INDEX_BOUNCE_COUNT => 0 - ); - } - - - /** - * Returns a Piwik_DataTable_Row containing default values for common stat, - * plus a column 'label' with the value $label - * - * @param string $label - * @return Piwik_DataTable_Row - */ - public function getNewInterestRowLabeled( $label ) - { - return new Piwik_DataTable_Row( - array( - Piwik_DataTable_Row::COLUMNS => array( 'label' => $label) - + $this->getNewInterestRow() - ) - ); - } - - /** - * Adds the given row $newRowToAdd to the existing $oldRowToUpdate passed by reference - * - * The rows are php arrays Name => value - * - * @param array $newRowToAdd - * @param array $oldRowToUpdate - */ - public function updateInterestStats( $newRowToAdd, &$oldRowToUpdate) - { - $oldRowToUpdate[Piwik_Archive::INDEX_NB_UNIQ_VISITORS] += $newRowToAdd[Piwik_Archive::INDEX_NB_UNIQ_VISITORS]; - $oldRowToUpdate[Piwik_Archive::INDEX_NB_VISITS] += $newRowToAdd[Piwik_Archive::INDEX_NB_VISITS]; - $oldRowToUpdate[Piwik_Archive::INDEX_NB_ACTIONS] += $newRowToAdd[Piwik_Archive::INDEX_NB_ACTIONS]; - $oldRowToUpdate[Piwik_Archive::INDEX_MAX_ACTIONS] = (float)max($newRowToAdd[Piwik_Archive::INDEX_MAX_ACTIONS], $oldRowToUpdate[Piwik_Archive::INDEX_MAX_ACTIONS]); - $oldRowToUpdate[Piwik_Archive::INDEX_SUM_VISIT_LENGTH] += $newRowToAdd[Piwik_Archive::INDEX_SUM_VISIT_LENGTH]; - $oldRowToUpdate[Piwik_Archive::INDEX_BOUNCE_COUNT] += $newRowToAdd[Piwik_Archive::INDEX_BOUNCE_COUNT]; - } -} - - diff --git a/modules/ArchiveProcessing/Period.php b/modules/ArchiveProcessing/Period.php deleted file mode 100644 index 3eef5ed2a0..0000000000 --- a/modules/ArchiveProcessing/Period.php +++ /dev/null @@ -1,270 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_ArchiveProcessing - */ - -/** - * Handles the archiving process for a period - * - * This class provides generic methods to archive data for a period (week / month / year). - * - * These methods are called by the plugins that do the logic of archiving their own data. \ - * They hook on the event 'ArchiveProcessing_Period.compute' - * - * @package Piwik_ArchiveProcessing - */ -class Piwik_ArchiveProcessing_Period extends Piwik_ArchiveProcessing -{ - /** - * Sums all values for the given field names $aNames over the period - * See @archiveNumericValuesGeneral for more information - * - * @param string|array - * @return Piwik_ArchiveProcessing_Record_Numeric - * - */ - public function archiveNumericValuesSum( $aNames ) - { - return $this->archiveNumericValuesGeneral($aNames, 'sum'); - } - - /** - * Get the maximum value for all values for the given field names $aNames over the period - * See @archiveNumericValuesGeneral for more information - * - * @param string|array - * @return Piwik_ArchiveProcessing_Record_Numeric - * - */ - public function archiveNumericValuesMax( $aNames ) - { - return $this->archiveNumericValuesGeneral($aNames, 'max'); - } - - /** - * Given a list of fields names, the method will fetch all their values over the period, and archive them using the given operation. - * - * For example if $operationToApply = 'sum' and $aNames = array('nb_visits', 'sum_time_visit') - * it will sum all values of nb_visits for the period (for example give the number of visits for the month by summing the visits of every day) - * - * @param array|string $aNames Array of strings or string containg the field names to select - * @param string $operationToApply Available operations = sum, max, min - * @return Piwik_ArchiveProcessing_Record_Numeric Returns the record if $aNames is a string, - * an array of Piwik_ArchiveProcessing_Record_Numeric indexed by their field names if aNames is an array of strings - */ - private function archiveNumericValuesGeneral($aNames, $operationToApply) - { - if(!is_array($aNames)) - { - $aNames = array($aNames); - } - - // fetch the numeric values and apply the operation on them - $results = array(); - foreach($this->archives as $archive) - { - foreach($aNames as $name) - { - if(!isset($results[$name])) - { - $results[$name] = 0; - } - $valueToSum = $archive->getNumeric($name); - - if($valueToSum !== false) - { - switch ($operationToApply) { - case 'sum': - $results[$name] += $valueToSum; - break; - case 'max': - $results[$name] = max($results[$name], $valueToSum); - break; - case 'min': - $results[$name] = min($results[$name], $valueToSum); - break; - default: - throw new Exception("Operation not applicable."); - break; - } - } - } - } - - // build the Record Numeric objects - $records = array(); - foreach($results as $name => $value) - { - $records[$name] = new Piwik_ArchiveProcessing_Record_Numeric( - $name, - $value - ); - } - - // if asked for only one field to sum - if(count($records) == 1) - { - return $records[$name]; - } - - // returns the array of records once summed - return $records; - } - - - /** - * This powerful method will compute the sum of DataTables over the period for the given fields $aRecordName. - * The resulting DataTable will be then added to queue of data to be recorded in the database. - * It will usually be called in a plugin that listens to the hook 'ArchiveProcessing_Period.compute' - * - * For example if $aRecordName = 'UserCountry_country' the method will select all UserCountry_country DataTable for the period - * (eg. the 31 dataTable of the last month), sum them, and create the Piwik_ArchiveProcessing_Record_BlobArray so that - * the resulting dataTable is AUTOMATICALLY recorded in the database. - * - * - * This method works on recursive dataTable. For example for the 'Actions' it will select all subtables of all dataTable of all the sub periods - * and get the sum. - * - * It returns an array that gives information about the "final" DataTable. The array gives for every field name, the number of rows in the - * final DataTable (ie. the number of distinct LABEL over the period) (eg. the number of distinct keywords over the last month) - * - * @param string|array Field name(s) of DataTable to select so we can get the sum - * @return array array ( - * nameTable1 => number of rows, - * nameTable2 => number of rows, - * ) - */ - public function archiveDataTable( $aRecordName, $maximumRowsInDataTableLevelZero = null, $maximumRowsInSubDataTable = null ) - { - if(!is_array($aRecordName)) - { - $aRecordName = array($aRecordName); - } - - $nameToCount = array(); - foreach($aRecordName as $recordName) - { - $table = $this->getRecordDataTableSum($recordName); - - $nameToCount[$recordName]['level0'] = $table->getRowsCount(); - $nameToCount[$recordName]['recursive'] = $table->getRowsCountRecursive(); - - $record = new Piwik_ArchiveProcessing_Record_BlobArray($recordName, $table->getSerialized( $maximumRowsInDataTableLevelZero, $maximumRowsInSubDataTable )); - } - return $nameToCount; - } - - /** - * This method selects all DataTables that have the name $name over the period. - * It calls the appropriate methods that sum all these tables together. - * The resulting DataTable is returned. - * - * @param string $name - * @return Piwik_DataTable - */ - protected function getRecordDataTableSum( $name ) - { - $table = new Piwik_DataTable; - foreach($this->archives as $archive) - { - $archive->preFetchBlob($name); - $datatableToSum = $archive->getDataTable($name); - $archive->loadSubDataTables($name, $datatableToSum); - $table->addDataTable($datatableToSum); - $archive->freeBlob($name); - } - return $table; - } - - protected function initCompute() - { - parent::initCompute(); - $this->archives = $this->loadSubperiodsArchive(); - } - - /** - * Returns the ID of the archived subperiods. - * - * @return array Array of the idArchive of the subperiods - */ - protected function loadSubperiodsArchive() - { - $periods = array(); - - // we first compute every subperiod of the archive - foreach($this->period->getSubperiods() as $period) - { - $archivePeriod = new Piwik_Archive_Single; - $archivePeriod->setSite( $this->site ); - $archivePeriod->setPeriod( $period ); - $archivePeriod->prepareArchive(); - - $periods[] = $archivePeriod; - } - return $periods; - } - - /** - * Main method to process logs for a period. - * The only logic done here is computing the number of visits, actions, etc. - * - * All the other reports are computed inside plugins listening to the event 'ArchiveProcessing_Period.compute'. - * See some of the plugins for an example. - * - * @return void - */ - protected function compute() - { - $this->archiveNumericValuesMax( 'max_actions' ); - $toSum = array( - 'nb_uniq_visitors', - 'nb_visits', - 'nb_actions', - 'sum_visit_length', - 'bounce_count', - ); - $record = $this->archiveNumericValuesSum($toSum); - - $this->isThereSomeVisits = ($record['nb_visits']->value != 0); - if($this->isThereSomeVisits === false) - { - return; - } - - Piwik_PostEvent('ArchiveProcessing_Period.compute', $this); - } - - /** - * Called at the end of the archiving process. - * Does some cleaning job in the database. - * - * @return void - */ - protected function postCompute() - { - parent::postCompute(); - - // we delete records that are now out of date - // in the case of a period we delete archives that were archived before the end of the period - // and only if they are at least 1 day old (so we don't delete archives computed today that may be stil valid) - $blobTable = $this->tableArchiveBlob->getTableName(); - $numericTable = $this->tableArchiveNumeric->getTableName(); - - $query = " DELETE - FROM %s - WHERE period > ? - AND DATE(ts_archived) <= date2 - AND date(ts_archived) < date_sub(CURRENT_DATE(), INTERVAL 1 DAY) - "; - - Zend_Registry::get('db')->query(sprintf($query, $blobTable), Piwik::$idPeriods['day']); - Zend_Registry::get('db')->query(sprintf($query, $numericTable), Piwik::$idPeriods['day']); - } - -} diff --git a/modules/ArchiveProcessing/Record.php b/modules/ArchiveProcessing/Record.php deleted file mode 100644 index 2dba870d19..0000000000 --- a/modules/ArchiveProcessing/Record.php +++ /dev/null @@ -1,55 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_ArchiveProcessing - */ - -require_once "ArchiveProcessing/Record/Blob.php"; -require_once "ArchiveProcessing/Record/BlobArray.php"; -require_once "ArchiveProcessing/Record/Numeric.php"; -require_once "ArchiveProcessing/Record/Manager.php"; - - -/** - * A Record is a tuple (name, value) to be saved in the database. - * At its creation, the record registers itself to the RecordManager. - * The record will then be automatically saved in the DB once the Archiving process is finished. - * - * We have two record types available: - * - numeric ; the value will be saved as float in the DB. - * It should be used for INTEGER, FLOAT - * - blob ; the value will be saved in a binary field in the DB - * It should be used for all the other types: PHP variables, STRING, serialized OBJECTS or ARRAYS, etc. - * - * @package Piwik_ArchiveProcessing - * @subpackage Piwik_ArchiveProcessing_Record - */ -abstract class Piwik_ArchiveProcessing_Record -{ - public $name; - public $value; - - function __construct( $name, $value) - { - $this->name = $name; - $this->value = $value; - Piwik_ArchiveProcessing_Record_Manager::getInstance()->registerRecord($this); - } - - public function delete() - { - Piwik_ArchiveProcessing_Record_Manager::getInstance()->unregister($this); - } - - public function __destruct() - { - } -} - - - diff --git a/modules/ArchiveProcessing/Record/Blob.php b/modules/ArchiveProcessing/Record/Blob.php deleted file mode 100644 index fd805c31d5..0000000000 --- a/modules/ArchiveProcessing/Record/Blob.php +++ /dev/null @@ -1,33 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id: Record.php 180 2008-01-17 16:32:37Z matt $ - * - * @package Piwik_ArchiveProcessing - */ - -/** - * Blob record. - * Example: $record = new Piwik_ArchiveProcessing_Record_Blob('visitor_names', serialize(array('piwik-fan', 'php', 'stevie-vibes'))); - * The value will be compressed before being saved in the DB. - * - * @package Piwik_ArchiveProcessing - * @subpackage Piwik_ArchiveProcessing_Record - */ -class Piwik_ArchiveProcessing_Record_Blob extends Piwik_ArchiveProcessing_Record -{ - public $name; - public $value; - function __construct( $name, $value) - { - $value = gzcompress($value); - parent::__construct( $name, $value ); - } - public function __toString() - { - return $this->name ." = BLOB";//". gzuncompress($this->value); - } -} diff --git a/modules/ArchiveProcessing/Record/BlobArray.php b/modules/ArchiveProcessing/Record/BlobArray.php deleted file mode 100644 index 4e3165489e..0000000000 --- a/modules/ArchiveProcessing/Record/BlobArray.php +++ /dev/null @@ -1,63 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id: Record.php 180 2008-01-17 16:32:37Z matt $ - * - * @package Piwik_ArchiveProcessing - */ - -/** - * Array of blob records. - * Useful for easily saving splited data in the DB. - * - * Example: $record = new Piwik_ArchiveProcessing_Record_BlobArray( - * 'veryLongBook', - * 0 => serialize( array( '1st chapter very long, 6MB of data we dont want to save' )), - * 1 => serialize( array( '2nd chapter very long, 8MB of data we dont want to save' )), - * 2 => serialize( array( '3rd chapter very long, 7MB of data we dont want to save' )), - * 3 => serialize( array( '4th chapter very long, 10MB of data we dont want to save' )), - * ); - * - * Will be saved in the DB as - * veryLongBook => X - * veryLongBook_1 => Y - * veryLongBook_2 => Z - * veryLongBook_3 => M - * - * @package Piwik_ArchiveProcessing - * @subpackage Piwik_ArchiveProcessing_Record - */ -class Piwik_ArchiveProcessing_Record_BlobArray extends Piwik_ArchiveProcessing_Record -{ - - function __construct( $name, $aValue) - { - foreach($aValue as $id => $value) - { - // for the parent Table we keep the name - // for example for the Table of searchEngines we keep the name 'referer_search_engine' - // but for the child table of 'Google' which has the ID = 9 the name would be 'referer_search_engine_9' - if($id == 0) - { - $newName = $name; - } - else - { - $newName = $name . '_' . $id; - } - $record = new Piwik_ArchiveProcessing_Record_Blob( $newName, $value ); - - } - } - public function __toString() - { - throw new Exception( 'Not valid' ); - } - public function delete() - { - throw new Exception( 'Not valid' ); - } -} diff --git a/modules/ArchiveProcessing/Record/Manager.php b/modules/ArchiveProcessing/Record/Manager.php deleted file mode 100644 index 1520492273..0000000000 --- a/modules/ArchiveProcessing/Record/Manager.php +++ /dev/null @@ -1,109 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id: Record.php 180 2008-01-17 16:32:37Z matt $ - * - * @package Piwik_ArchiveProcessing - */ - -/** - * Every new Piwik_ArchiveProcessing_Record will be recorded to this manager when created. - * At the end of the archiving process, the ArchiveProcessing will getRecords() to save them in the db. - * This class is singleton. - * - * @package Piwik_ArchiveProcessing - * @subpackage Piwik_ArchiveProcessing_Record - */ -class Piwik_ArchiveProcessing_Record_Manager -{ - // array of Piwik_ArchiveProcessing_Record to be recorded in the DB - protected $records = array(); - - static private $instance = null; - protected function __construct() - {} - - /** - * Singleton, returns instance - * - * @return Piwik_ArchiveProcessing_Record_Manager - */ - static public function getInstance() - { - if (self::$instance == null) - { - $c = __CLASS__; - self::$instance = new $c(); - } - return self::$instance; - } - - /** - * Method called by Record objects to register themselves. - * All records registered here will be saved in the DB at the end of the archiving process. - * @return void - */ - public function registerRecord( $record ) - { - $this->records[$record->name] = $record; - } - - /** - * Removes a record from the Record Manager. - * - * @return void - */ - public function unregister( $deleteRecord ) - { - unset($this->records[$deleteRecord->name]); - } - - /** - * Returns a string containing the "name : value" of the record - * @return string - */ - public function toString() - { - $str = ''; - foreach($this->records as $record) - { - $str .= $record . "<br>\n"; - } - return $str; - } - - /** - * @return string - */ - public function __toString() - { - return $this->toString(); - } - - /** - * Returns the list of all the records that have to created in the database. - * - * @return array of Records - */ - public function getRecords() - { - return $this->records; - } - - /** - * Delete all records saved in the Manager. - * @return void - */ - public function deleteAll() - { - foreach($this->records as $key => $record) - { - unset($this->records[$key]); - } - $this->records = array(); - } -} - diff --git a/modules/ArchiveProcessing/Record/Numeric.php b/modules/ArchiveProcessing/Record/Numeric.php deleted file mode 100644 index f7f206e14e..0000000000 --- a/modules/ArchiveProcessing/Record/Numeric.php +++ /dev/null @@ -1,30 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id: Record.php 180 2008-01-17 16:32:37Z matt $ - * - * @package Piwik_ArchiveProcessing - */ - -/** - * Numeric record. - * Example: $record = new Piwik_ArchiveProcessing_Record_Numeric('nb_visitors_live', 15); - * - * @package Piwik_ArchiveProcessing - * @subpackage Piwik_ArchiveProcessing_Record - */ -class Piwik_ArchiveProcessing_Record_Numeric extends Piwik_ArchiveProcessing_Record -{ - function __construct( $name, $value) - { - parent::__construct( $name, $value ); - } - - public function __toString() - { - return $this->name ." = ". $this->value; - } -} diff --git a/modules/Auth.php b/modules/Auth.php deleted file mode 100644 index fac2a95f4f..0000000000 --- a/modules/Auth.php +++ /dev/null @@ -1,52 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik - */ - -interface Piwik_Auth { - /** - * @return Piwik_Auth_Result - */ - public function authenticate(); -} - -/** - * - * @package Piwik - */ -class Piwik_Auth_Result extends Zend_Auth_Result -{ - /** - * token_auth parameter used to authenticate in the API - * - * @var string - */ - protected $_token_auth = null; - - const SUCCESS_SUPERUSER_AUTH_CODE = 42; - - public function __construct($code, $login, $token_auth, array $messages = array()) - { - // Piwik_Auth_Result::SUCCESS_SUPERUSER_AUTH_CODE, Piwik_Auth_Result::SUCCESS, Piwik_Auth_Result::FAILURE - $this->_code = (int)$code; - $this->_identity = $login; - $this->_messages = $messages; - $this->_token_auth = $token_auth; - } - - /** - * Returns the token_auth to authenticate the current user in the API - * - * @return string - */ - public function getTokenAuth() - { - return $this->_token_auth; - } -} diff --git a/modules/Common.php b/modules/Common.php deleted file mode 100644 index 8e145158ad..0000000000 --- a/modules/Common.php +++ /dev/null @@ -1,643 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_Helper - */ - -/** - * Static class providing functions used by both the CORE of Piwik and the visitor logging engine. - * - * 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_Helper - */ -class Piwik_Common -{ - /** - * Const used to map the referer type to an integer in the log_visit table - * - */ - const REFERER_TYPE_DIRECT_ENTRY = 1; - const REFERER_TYPE_SEARCH_ENGINE = 2; - const REFERER_TYPE_WEBSITE = 3; - const REFERER_TYPE_PARTNER = 4; - const REFERER_TYPE_NEWSLETTER = 5; - const REFERER_TYPE_CAMPAIGN = 6; - - /** - * Flag used with htmlspecialchar - * See php.net/htmlspecialchars - * - */ - const HTML_ENCODING_QUOTE_STYLE = ENT_COMPAT; - - - /** - * Returns the path and query part from a URL. - * Eg. http://piwik.org/test/index.php?module=CoreHome will return /test/index.php?module=CoreHome - * - * @param string $url either http://piwik.org/test or / - * @return string - */ - static function getPathAndQueryFromUrl($url) - { - $parsedUrl = parse_url( $url ); - - $result = ''; - - if(isset($parsedUrl['path'])) - { - $result .= substr($parsedUrl['path'], 1); - } - - if(isset($parsedUrl['query'])) - { - $result .= '?'.$parsedUrl['query']; - } - - return $result; - } - - /** - * Returns the value of a GET parameter $parameter in an URL query $urlQuery - * - * @param string $urlQuery result of parse_url()['query'] and htmlentitied (& is &) eg. module=test&action=toto or ?page=test - * @param string $param - * - * @return string|bool Parameter value if found (can be the empty string!), false if not found - */ - static public function getParameterFromQueryString( $urlQuery, $parameter) - { - $nameToValue = self::getArrayFromQueryString($urlQuery); - - if(isset($nameToValue[$parameter])) - { - return $nameToValue[$parameter]; - } - return false; - } - - /** - * Returns an URL query string in an array format - * The input query string should be htmlspecialchar'ed - * - * @param string urlQuery - * @return array array( param1=> value1, param2=>value2) - */ - static public function getArrayFromQueryString( $urlQuery ) - { - if(strlen($urlQuery) == 0) - { - return array(); - } - if($urlQuery[0] == '?') - { - $urlQuery = substr($urlQuery, 1); - } - - $separator = '&'; - - $urlQuery = $separator . $urlQuery; - // $urlQuery = str_replace(array('%20'), ' ', $urlQuery); - $refererQuery = trim($urlQuery); - - $values = explode($separator, $refererQuery); - - $nameToValue = array(); - - foreach($values as $value) - { - if( false !== strpos($value, '=')) - { - $exploded = explode('=',$value); - $nameToValue[$exploded[0]] = $exploded[1]; - } - } - return $nameToValue; - } - - /** - * Returns true if the string is a valid filename - * File names that start with a-Z or 0-9 and contain a-Z, 0-9, underscore(_), dash(-), and dot(.) will be accepted. - * File names beginning with anything but a-Z or 0-9 will be rejected (including .htaccess for example). - * File names containing anything other than above mentioned will also be rejected (file names with spaces won't be accepted). - * - * @param string filename - * @return bool - * - */ - static public function isValidFilename($filename) - { - return (false !== ereg("(^[a-zA-Z0-9]+([a-zA-Z\_0-9\.-]*))$" , $filename)); - } - /** - * Returns true if the string passed may be a URL. - * We don't need a precise test here because the value comes from the website - * tracked source code and the URLs may look very strange. - * - * @param string $url - * @return bool - */ - static function isLookLikeUrl( $url ) - { - return ereg('^(ftp|news|http|https)?://[A-Za-z0-9\/_.-?&]*', $url); - } - - /** - * Returns the variable after cleaning operations. - * NB: The variable still has to be escaped before going into a SQL Query! - * - * If an array is passed the cleaning is done recursively on all the sub-arrays. \ - * The keys of the array are filtered as well! - * - * How this method works: - * - The variable returned has been htmlspecialchars to avoid the XSS security problem. - * - The single quotes are not protected so "Piwik's amazing" will still be "Piwik's amazing". - * - * - Transformations are: - * - '&' (ampersand) becomes '&' - * - '"'(double quote) becomes '"' - * - '<' (less than) becomes '<' - * - '>' (greater than) becomes '>' - * - It handles the magic_quotes setting. - * - A non string value is returned without modification - * - * @param mixed The variable to be cleaned - * @return mixed The variable after cleaning - */ - static public function sanitizeInputValues($value) - { - if(is_numeric($value)) - { - return $value; - } - elseif(is_string($value)) - { - $value = htmlspecialchars($value, Piwik_Common::HTML_ENCODING_QUOTE_STYLE, 'UTF-8'); - - // Undo the damage caused by magic_quotes -- only before php 5.3 as it is now deprecated - if ( version_compare(phpversion(), '5.3') === -1 - && get_magic_quotes_gpc()) - { - $value = stripslashes($value); - } - } - elseif (is_array($value)) - { - foreach (array_keys($value) as $key) - { - $newKey = $key; - $newKey = Piwik_Common::sanitizeInputValues($newKey); - if ($key != $newKey) - { - $value[$newKey] = $value[$key]; - unset($value[$key]); - } - - $value[$newKey] = Piwik_Common::sanitizeInputValues($value[$newKey]); - } - } - elseif( !is_null($value) - && !is_bool($value) - ) - { - throw new Exception("The value to escape has not a supported type. Value = ".var_export($value, true)); - } - return $value; - } - - /** - * Returns a variable from the $_REQUEST superglobal. - * If the variable doesn't have a value or an empty value, returns the defaultValue if specified. - * If the variable doesn't have neither a value nor a default value provided, an exception is raised. - * - * @param string $varName name of the variable - * @param string $varDefault default value. If '', and if the type doesn't match, exit() ! - * @param string $varType Expected type, the value must be one of the following: array, numeric, int, integer, string - * - * @exception if the variable type is not known - * @exception if the variable we want to read doesn't have neither a value nor a default value specified - * - * @return mixed The variable after cleaning - */ - static public function getRequestVar($varName, $varDefault = null, $varType = null, $requestArrayToUse = null) - { - if(is_null($requestArrayToUse)) - { - $requestArrayToUse = $_REQUEST; - } - - $varDefault = self::sanitizeInputValues( $varDefault ); - - if($varType == 'int') - { - // settype accepts only integer - // 'int' is simply a shortcut for 'integer' - $varType = 'integer'; - } - - // there is no value $varName in the REQUEST so we try to use the default value - if(empty($varName) - || !isset($requestArrayToUse[$varName]) - || ( !is_array($requestArrayToUse[$varName]) - && strlen($requestArrayToUse[$varName]) === 0 - ) - ) - { - if( is_null($varDefault)) - { - throw new Exception("\$varName '$varName' doesn't have value in \$_REQUEST and doesn't have a" . - " \$varDefault value"); - } - else - { - if( !is_null($varType) - && in_array($varType, array('string', 'integer', 'array')) - ) - { - settype($varDefault, $varType); - } - return $varDefault; - } - } - - // Normal case, there is a value available in REQUEST for the requested varName - $value = self::sanitizeInputValues( $requestArrayToUse[$varName] ); - - if( !is_null($varType)) - { - $ok = false; - - if($varType == 'string') - { - if(is_string($value)) $ok = true; - } - elseif($varType == 'numeric') - { - if(is_numeric($value) || $value==(int)$value || $value==(float)$value) $ok = true; - } - elseif($varType == 'integer') - { - if(is_int($value) || $value==(int)$value) $ok = true; - } - elseif($varType == 'float') - { - if(is_float($value) || $value==(float)$value) $ok = true; - } - elseif($varType == 'array') - { - if(is_array($value)) $ok = true; - } - else - { - throw new Exception("\$varType specified is not known. It should be one of the following: array, numeric, int, integer, float, string"); - } - - // The type is not correct - if($ok === false) - { - if($varDefault === null) - { - throw new Exception("\$varName '$varName' doesn't have a correct type in \$_REQUEST and doesn't " . - "have a \$varDefault value"); - } - // we return the default value with the good type set - else - { - settype($varDefault, $varType); - return $varDefault; - } - } - } - - return $value; - } - - /** - * Returns a 32 characters long uniq ID - * - * @return string 32 chars - */ - static public function generateUniqId() - { - return md5(uniqid(rand(), true)); - } - - /** - * Returns a 3 letters ID for the operating system part, given a user agent string. - * @see modules/DataFiles/OS.php for the list of OS (also available in $GLOBALS['Piwik_Oslist']) - * If the OS cannot be identified in the user agent, returns 'UNK' - * - * @param string $userAgent - * - * @return string - */ - static public function getOs($userAgent) - { - - require_once "modules/DataFiles/OS.php"; - $osNameToId = $GLOBALS['Piwik_Oslist']; - - foreach($osNameToId as $key => $value) - { - if ($ok = ereg($key, $userAgent)) - { - return $value; - } - } - return 'UNK'; - } - - /** - * Returns the browser information from the user agent string. - * - * @see modules/DataFiles/Browsers.php for the list of OS (also available in $GLOBALS['Piwik_BrowserList']) - * - * @param string $userAgent - * @return array array( 'name' => '', // 2 letters ID or 'UNK' for an unknown browser - * 'major_number' => '', // 2 in firefox 2.0.12 - * 'minor_number' => '', // 0 in firefox 2.0.12 - * 'version' => '' // major_number.minor_number - * ); - */ - static public function getBrowserInfo($userAgent) - { - - require_once "modules/DataFiles/Browsers.php"; - - $browsers = $GLOBALS['Piwik_BrowserList']; - - $info = array( - 'name' => 'UNK', - 'major_number' => '', - 'minor_number' => '', - 'version' => '' - ); - - $browser = ''; - foreach($browsers as $key => $value) - { - if(!empty($browser)) $browser .= "|"; - $browser .= $key; - } - - $results = array(); - - // added fix for Mozilla Suite detection - if ((preg_match_all("/(mozilla)[\/\sa-z;.0-9-(]+rv:([0-9]+)([.0-9a-z]+)\) gecko\/[0-9]{8}$/i", $userAgent, $results)) - || (preg_match_all("/($browser)[\/\sa-z(]*([0-9]+)([\.0-9a-z]+)?/i", $userAgent, $results)) - ) - { - $count = count($results[0])-1; - - // browser code - $info['name'] = $browsers[strtolower($results[1][$count])]; - - // majeur version number (7 in mozilla 1.7 - $info['major_number'] = $results[2][$count]; - - // is an minor version number ? If not, 0 - $match = array(); - - preg_match('/([.\0-9]+)?([\.a-z0-9]+)?/i', $results[3][$count], $match); - - if(isset($match[1])) - { - // find minor version number (7 in mozilla 1.7, 9 in firefox 0.9.3) - $info['minor_number'] = substr($match[1], 0, 2); - } - else - { - $info['minor_number'] = '.0'; - } - - $info['version'] = $info['major_number'] . $info['minor_number']; - } - return $info; - } - - - /** - * Returns the best possible IP of the current user, in the format A.B.C.D - * - * @return string ip - */ - static public function getIp() - { - if(isset($_SERVER['HTTP_CLIENT_IP']) - && ($ip = Piwik_Common::getFirstIpFromList($_SERVER['HTTP_CLIENT_IP'])) - && strpos($ip, "unknown") === false) - { - return $ip; - } - elseif(isset($_SERVER['HTTP_X_FORWARDED_FOR']) - && $ip = Piwik_Common::getFirstIpFromList($_SERVER['HTTP_X_FORWARDED_FOR']) - && isset($ip) - && !empty($ip) - && strpos($ip, "unknown")===false ) - { - return $ip; - } - elseif( isset($_SERVER['HTTP_CLIENT_IP']) - && strlen( Piwik_Common::getFirstIpFromList($_SERVER['HTTP_CLIENT_IP']) ) != 0 ) - { - return Piwik_Common::getFirstIpFromList($_SERVER['HTTP_CLIENT_IP']); - } - else if( isset($_SERVER['HTTP_X_FORWARDED_FOR']) - && strlen ($ip = Piwik_Common::getFirstIpFromList($_SERVER['HTTP_X_FORWARDED_FOR'])) != 0) - { - return $ip; - } - elseif(isset($_SERVER['REMOTE_ADDR'])) - { - return Piwik_Common::getFirstIpFromList($_SERVER['REMOTE_ADDR']); - } - else - { - return '0.0.0.0'; - } - } - - - /** - * Returns the first element of a comma separated list of IPs - * - * @param string $ip - * - * @return string first element before ',' - */ - static private function getFirstIpFromList($ip) - { - $p = strpos($ip, ','); - if($p!==false) - { - return trim(Piwik_Common::sanitizeInputValues(substr($ip, 0, $p))); - } - return trim(Piwik_Common::sanitizeInputValues($ip)); - } - - - /** - * Returns the continent of a given country - * - * @param string Country 2 letters isocode - * - * @return string Continent (3 letters code : afr, asi, eur, amn, ams, oce) - */ - static public function getContinent($country) - { - require_once "modules/DataFiles/Countries.php"; - - $countryList = $GLOBALS['Piwik_CountryList']; - - if(isset($countryList[$country][0])) - { - return $countryList[$country][0]; - } - else - { - return 'unk'; - } - } - - /** - * Returns the visitor country based only on the Browser 'accepted language' information - * - * @param string $lang browser lang - * - * @return string 2 letters ISO code - */ - static public function getCountry( $lang ) - { - require_once "modules/DataFiles/Countries.php"; - - $countryList = $GLOBALS['Piwik_CountryList']; - - $replaceLangCodeByCountryCode = array( - // replace cs language (Serbia Montenegro country code) with czech country code - 'cs' => 'cz', - // replace sv language (El Salvador country code) with sweden country code - 'sv' => 'se', - // replace fa language (Unknown country code) with Iran country code - 'fa' => 'ir', - // replace ja language (Unknown country code) with japan country code - 'ja' => 'jp', - // replace ko language (Unknown country code) with corée country code - 'ko' => 'kr', - // replace he language (Unknown country code) with Israel country code - 'he' => 'il', - // replace da language (Unknown country code) with Danemark country code - 'da' => 'dk', - // replace gb code with UK country code - 'gb' => 'uk', - ); - - - if(empty($lang) || strlen($lang) < 2) - { - return 'xx'; - } - - $lang = str_replace( array_keys($replaceLangCodeByCountryCode), - array_values($replaceLangCodeByCountryCode), - $lang - ); - - // Ex: "fr" - if(strlen($lang) == 2) - { - if(isset($countryList[$lang])) - { - return $lang; - } - } - - // when comma - $offcomma = strpos($lang, ','); - - if($offcomma == 2) - { - // in 'fr,en-us', keep first two chars - $domain = substr($lang, 0, 2); - if(isset($countryList[$domain])) - { - return $domain; - } - - // catch the second language Ex: "fr" in "en,fr" - $domain = substr($lang, 3, 2); - if(isset($countryList[$domain])) - { - return $domain; - } - } - - // detect second code Ex: "be" in "fr-be" - $off = strpos($lang, '-'); - if($off!==false) - { - $domain = substr($lang, $off+1, 2); - - if(isset($countryList[$domain])) - { - return $domain; - } - } - - // catch the second language Ex: "fr" in "en;q=1.0,fr;q=0.9" - if(preg_match("/^[a-z]{2};q=[01]\.[0-9],(?P<domain>[a-z]{2});/", $lang, $parts)) - { - $domain = $parts['domain']; - - if(isset($GLOBALS['countryList'][$domain][0])) - { - return $domain; - } - } - - // finally try with the first ever langage code - $domain = substr($lang, 0, 2); - if(isset($countryList[$domain])) - { - return $domain; - } - - // at this point we really can't guess the country - return 'xx'; - } - - - /** - * Generate random string - * - * @param string $length string length - * @param string $alphabet characters allowed in random string - * - * @return string random string with given length - */ - public static function getRandomString($length = 16, $alphabet = "abcdefghijklmnoprstuvwxyz0123456789") - { - $chars = $alphabet; - $str = ''; - - list($usec, $sec) = explode(" ", microtime()); - $seed = ((float)$sec+(float)$usec)*100000; - mt_srand($seed); - - for($i = 0; $i < $length; $i++) - { - $rand_key = mt_rand(0, strlen($chars)-1); - $str .= substr($chars, $rand_key, 1); - } - return str_shuffle($str); - } -} - - diff --git a/modules/Config.php b/modules/Config.php deleted file mode 100755 index f768eb139b..0000000000 --- a/modules/Config.php +++ /dev/null @@ -1,223 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_Helper - */ - -require_once "Zend/Config/Ini.php"; -require_once "Zend/Registry.php"; - -/** - * This class is used to access configuration files values. - * You can also set these values, the updated configuration files will be written at the end of the script execution. - * - * Example reading a value from the configuration file: - * $minValue = Zend_Registry::get('config')->General->minimum_memory_limit; - * - * will read the value minimumMemoryLimit under the [General] section of the config file - * - * @package Piwik_Helper - */ -class Piwik_Config -{ - /** - * When the user modifies the configuration file and there is one value missing, we suggest the default config file - * - * @var string - */ - protected $urlToPiwikHelpMissingValueInConfigurationFile = - 'http://dev.piwik.org/trac/browser/trunk/config/global.ini.php?format=raw'; - - protected $defaultConfig = null; - protected $userConfig = null; - protected $pathIniFileUserConfig = null; - protected $pathIniFileDefaultConfig = null; - protected $configFileUpdated = false; - public $doWriteFileWhenUpdated = true; - - /** - * Storing the correct cwd() because the value is not correct in the destructor - * "The working directory in the script shutdown phase can be different with some SAPIs (e.g. Apache)." - * - * @see http://bugs.php.net/bug.php?id=34206 - */ - protected $correctCwd; - - /** - * Returns default relative path for configuration file - * - * @return string - */ - static public function getDefaultUserConfigPath() - { - return 'config/config.ini.php'; - } - - /** - * Builds the Config object, given the optional path for the user INI file - * If not specified, it will use the default path - * - * @param string $pathIniFileUserConfig - */ - function __construct($pathIniFileUserConfig = null) - { - Zend_Registry::set('config', $this); - - $this->pathIniFileDefaultConfig = 'config/global.ini.php'; - if(is_null($pathIniFileUserConfig)) - { - $this->pathIniFileUserConfig = self::getDefaultUserConfigPath(); - } - else - { - $this->pathIniFileUserConfig = $pathIniFileUserConfig; - } - - $this->defaultConfig = new Zend_Config_Ini($this->pathIniFileDefaultConfig, null, true); - - if(!Zend_Loader::isReadable($this->pathIniFileUserConfig)) - { - throw new Exception("The configuration file {$this->pathIniFileUserConfig} has not been found."); - } - $this->userConfig = new Zend_Config_Ini($this->pathIniFileUserConfig, null, true); - - // see http://bugs.php.net/bug.php?id=34206 - $this->correctCwd = getcwd(); - } - - /** - * At the script shutdown, we save the new configuration file, if the user has set some values - * - */ - function __destruct() - { - if($this->configFileUpdated === true - && $this->doWriteFileWhenUpdated === true) - { - $configFile = "; <?php exit; ?> DO NOT REMOVE THIS LINE\n"; - $configFile .= "; file automatically generated during the piwik installation process (and updated later by some other modules)\n"; - - foreach($this->userConfig as $section => $arraySection) - { - $arraySection = $arraySection->toArray(); - $configFile .= "[$section]\n"; - foreach($arraySection as $name => $value) - { - if(is_numeric($name)) - { - $name = $section; - $value = array($value); - } - - if(is_array($value)) - { - foreach($value as $currentValue) - { - $configFile .= $name."[] = $currentValue\n"; - } - } - else - { - // hack: we add " " around the password because when requesting this data using Zend_Config - // the toArray removes the " around the value - if( ($section == 'database' || $section == 'database_tests') - && $name == 'password') - { - $value = '"'.$value.'"'; - } - - $configFile .= $name." = $value\n"; - } - } - $configFile .= "\n"; - } - - chdir($this->correctCwd); - file_put_contents($this->getDefaultUserConfigPath(), $configFile ); - } - } - - /** - * If called, we use the "testing" environment, which means using the database_tests and log_tests sections - * for DB & Log configuration. - * - * @return void - * - */ - public function setTestEnvironment() - { - $this->database = $this->database_tests; - $this->log = $this->log_tests; - } - - /** - * Called when setting configuration values eg. - * Zend_Registry::get('config')->superuser = $_SESSION['superuser_infos']; - * - * The values will be saved in the configuration file at the end of the script @see __destruct() - * - * @param string $name - * @param mixed $value - */ - public function __set($name, $value) - { - $this->checkWritePermissionOnFile(); - if(!is_null($this->userConfig)) - { - if($this->userConfig->$name != $value) - { - $this->configFileUpdated = true; - } - $this->userConfig->$name = $value; - } - else - { - $this->defaultConfig->$name = $value; - } - } - - protected function checkWritePermissionOnFile() - { - static $enoughPermission = null; - - if(is_null($enoughPermission)) - { - if($this->doWriteFileWhenUpdated) - { - Piwik_FrontController::checkDirectoriesWritableOrDie( array('/config') ); - } - $enoughPermission = true; - } - return $enoughPermission; - } - - /** - * Called when getting a configuration value, eg. Zend_Registry::get('config')->superuser->login - * - * @param string $name - * @return mixed value - * - * @throws exception if the value was not found in the configuration file - */ - public function __get($name) - { - if( !is_null($this->userConfig) - && null !== ($valueInUserConfig = $this->userConfig->$name)) - { - return $valueInUserConfig; - } - if(null !== ($valueInDefaultConfig = $this->defaultConfig->$name)) - { - return $valueInDefaultConfig; - } - - throw new Exception("The configuration parameter $name couldn't be found in your configuration file. - <br>Try to replace your default configuration file ({$this->pathIniFileDefaultConfig}) with - the <a href='".$this->urlToPiwikHelpMissingValueInConfigurationFile."'>default piwik configuration file</a> "); - } -} diff --git a/modules/Controller.php b/modules/Controller.php deleted file mode 100644 index 9e672ad1d7..0000000000 --- a/modules/Controller.php +++ /dev/null @@ -1,208 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik - */ - -/** - * Parent class of all plugins Controllers (located in /plugins/PluginName/Controller.php - * It defines some helper functions controllers can use. - * - * @package Piwik - */ -abstract class Piwik_Controller -{ - /** - * Plugin name, eg. Referers - * @var string - */ - protected $pluginName; - - /** - * Date string - * - * @var string - */ - protected $strDate; - - /** - * Piwik_Date object or null if the requested date is a range - * - * @var Piwik_Date|null - */ - protected $date; - - /** - * Builds the controller object, reads the date from the request, extracts plugin name from - * - */ - function __construct() - { - $aPluginName = explode('_', get_class($this)); - $this->pluginName = $aPluginName[1]; - $this->strDate = Piwik_Common::getRequestVar('date', 'yesterday','string'); - - // the date looks like YYYY-MM-DD we can build it - try{ - $this->date = Piwik_Date::factory($this->strDate); - $this->strDate = $this->date->toString(); - } catch(Exception $e){ - // the date looks like YYYY-MM-DD,YYYY-MM-DD or other format - // case the date looks like a range - $this->date = null; - } - } - - /** - * Returns the name of the default method that will be called - * when visiting: index.php?module=PluginName without the action parameter - * - * @return string - */ - function getDefaultAction() - { - return 'index'; - } - - /** - * Given an Object implementing Piwik_iView interface, we either: - * - echo the output of the rendering if fetch = false - * - returns the output of the rendering if fetch = true - * - * @param Piwik_ViewDataTable $view - * @param bool $fetch - * @return string|void - */ - protected function renderView( Piwik_ViewDataTable $view, $fetch) - { - $view->main(); - $rendered = $view->getView()->render(); - if($fetch) - { - return $rendered; - } - echo $rendered; - } - - /** - * Returns a ViewDataTable object of an Evolution graph - * for the last30 days/weeks/etc. of the current period, relative to the current date. - * - * @param string $currentModuleName - * @param string $currentControllerAction - * @param string $apiMethod - * @return Piwik_ViewDataTable_GenerateGraphHTML_ChartEvolution - */ - protected function getLastUnitGraph($currentModuleName, $currentControllerAction, $apiMethod) - { - require_once "ViewDataTable/GenerateGraphHTML.php"; - $view = Piwik_ViewDataTable::factory('graphEvolution'); - $view->init( $currentModuleName, $currentControllerAction, $apiMethod ); - - // if the date is not yet a nicely formatted date range ie. YYYY-MM-DD,YYYY-MM-DD we build it - // otherwise the current controller action is being called with the good date format already so it's fine - // see constructor - if( !is_null($this->date)) - { - $view->setParametersToModify( - $this->getGraphParamsModified( array('date'=>$this->strDate)) - ); - } - - return $view; - } - - - /** - * Returns the array of new processed parameters once the parameters are applied. - * For example: if you set range=last30 and date=2008-03-10, - * the date element of the returned array will be "2008-02-10,2008-03-10" - * - * Parameters you can set: - * - range: last30, previous10, etc. - * - date: YYYY-MM-DD, today, yesterday - * - period: day, week, month, year - * - * @param array paramsToSet = array( 'date' => 'last50', 'viewDataTable' =>'sparkline' ) - */ - protected function getGraphParamsModified($paramsToSet = array()) - { - if(!isset($paramsToSet['range'])) - { - $range = 'last30'; - } - else - { - $range = $paramsToSet['range']; - } - - if(!isset($paramsToSet['date'])) - { - $endDate = $this->strDate; - } - else - { - $endDate = $paramsToSet['date']; - } - - if(!isset($paramsToSet['period'])) - { - $period = Piwik_Common::getRequestVar('period'); - } - else - { - $period = $paramsToSet['period']; - } - - $last30Relative = new Piwik_Period_Range($period, $range ); - - $last30Relative->setDefaultEndDate(Piwik_Date::factory($endDate)); - - $paramDate = $last30Relative->getDateStart()->toString() . "," . $last30Relative->getDateEnd()->toString(); - - $params = array_merge($paramsToSet , array( 'date' => $paramDate ) ); - - return $params; - } - - /** - * Returns a numeric value from the API. - * Works only for API methods that originally returns numeric values (there is no cast here) - * - * @param string $methodToCall, eg. Referers.getNumberOfDistinctSearchEngines - * @return int|float - */ - protected function getNumericValue( $methodToCall ) - { - $requestString = 'method='.$methodToCall.'&format=original'; - $request = new Piwik_API_Request($requestString); - return $request->process(); - } - - /** - * Returns the current URL to use in a <img src=X> to display a sparkline. - * $action must be the name of a Controller method that requests data using the Piwik_ViewDataTable::factory - * It will automatically build a sparkline by setting the viewDataTable=sparkline parameter in the URL. - * It will also computes automatically the 'date' for the 'last30' days/weeks/etc. - * - * @param string $action, eg. method name of the controller to call in the img src - * @return string the generated URL - */ - protected function getUrlSparkline( $action ) - { - $params = $this->getGraphParamsModified( - array( 'viewDataTable' => 'sparkline', - 'action' => $action, - 'module' => $this->pluginName) - ); - $url = Piwik_Url::getCurrentQueryStringWithParametersModified($params); - return $url; - } - - -}
\ No newline at end of file diff --git a/modules/Cookie.php b/modules/Cookie.php deleted file mode 100644 index 9ad3680e25..0000000000 --- a/modules/Cookie.php +++ /dev/null @@ -1,282 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_Helper - */ - - -/** - * Simple class to handle the cookies: - * - read a cookie values - * - edit an existing cookie and save it - * - create a new cookie, set values, expiration date, etc. and save it - * - * @package Piwik_Helper - */ -class Piwik_Cookie -{ - /** - * The name of the cookie - */ - protected $name = null; - - /** - * The expire time for the cookie (expressed in UNIX Timestamp) - */ - protected $expire = null; - - /** - * The content of the 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; - - if(is_null($expire) - || !is_numeric($expire) - || $expire <= 0) - { - $this->expire = $this->getDefaultExpire(); - } - - if($this->isCookieFound()) - { - $this->loadContentFromCookie(); - } - } - - /** - * 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; - } - - /** - * We don't use the setcookie function because it is buggy for some PHP versions. - * - * Taken from http://php.net/setcookie - */ - protected function setCookie($Name, $Value, $Expires, $Path = '', $Domain = '', $Secure = false, $HTTPOnly = false) - { - if (!empty($Domain)) - { - // Fix the domain to accept domains with and without 'www.'. - if (strtolower(substr($Domain, 0, 4)) == 'www.') $Domain = substr($Domain, 4); - - $Domain = '.' . $Domain; - - // Remove port information. - $Port = strpos($Domain, ':'); - if ($Port !== false) $Domain = substr($Domain, 0, $Port); - } - - $header = 'Set-Cookie: ' . rawurlencode($Name) . '=' . rawurlencode($Value) - . (empty($Expires) ? '' : '; expires=' . gmdate('D, d-M-Y H:i:s', $Expires) . ' GMT') - . (empty($Path) ? '' : '; path=' . $Path) - . (empty($Domain) ? '' : '; domain=' . $Domain) - . (!$Secure ? '' : '; secure') - . (!$HTTPOnly ? '' : '; HttpOnly'); - - header($header, false); - } - - /** - * We set the privacy policy header - * - * @return void - */ - protected function setP3PHeader() - { - header("P3P: CP='OTI DSP COR NID STP UNI OTPa OUR'"); - } - - /** - * Delete the cookie - * - * @return void - */ - public function delete() - { - $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(); - $this->setCookie( $this->name, $this->generateContentString(), $this->expire); - } - - /** - * 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. - * - * @return void - */ - protected function loadContentFromCookie() - { - $cookieStr = $_COOKIE[$this->name]; - - $values = explode( self::VALUE_SEPARATOR, $cookieStr); - foreach($values as $nameValue) - { - $equalPos = strpos($nameValue, '='); - $varName = substr($nameValue,0,$equalPos); - $varValue = substr($nameValue,$equalPos+1); - - // no numeric value are base64 encoded so we need to decode them - if(!is_numeric($varValue)) - { - $varValue = base64_decode($varValue); - - // some of the values may be serialized array so we try to unserialize it - if( ($arrayValue = @unserialize($varValue)) !== false - // we set the unserialized version only for arrays as you can have set a serialized string on purpose - && is_array($arrayValue) - ) - { - $varValue = $arrayValue; - } - } - - $this->set($varName, $varValue); - } - } - - /** - * Returns the string to save in the cookie from the $this->value array of values. - * It goes through the array and generates the cookie content string. - * @return string Cookie content - */ - protected function generateContentString() - { - $cookieStr = ''; - foreach($this->value as $name=>$value) - { - if(is_array($value)) - { - $value = serialize($value); - } - $value = base64_encode($value); - - $cookieStr .= "$name=$value" . self::VALUE_SEPARATOR; - } - $cookieStr = substr($cookieStr, 0, strlen($cookieStr)-1); - return $cookieStr; - } - - /** - * Registers a new name => value association in the cookie. - * - * Registering new values is optimal if the value is a numeric value. - * If the value is a string, it will be saved as a base64 encoded string. - * 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 - * - */ - public function set( $name, $value ) - { - $name = self::escapeValue($name); - $this->value[$name] = $value; - } - - /** - * Returns the value defined by $name from the cookie. - * - * @param string|integer Index name of the value to return - * @return mixed The value if found, false if the value is not found - */ - public function get( $name ) - { - $name = self::escapeValue($name); - 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"; - foreach($this->value as $name => $value ) - { - $str .= $name . " = " . var_export($this->get($name), true) . "<br>\n"; - } - $str .= "--> <br>\n"; - 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_Cookie( 'piwik_logstats', 86400); -//echo $c; -//$c->set(1,1); -//$c->set('test',1); -//$c->set('test2','test=432:gea785'); -//$c->set('test3',array('test=432:gea785')); -//$c->set('test4',array(array(0=>1),1=>'test')); -//echo $c; -//echo "<br>"; -//$v=$c->get('more!'); -//if(empty($v)) $c->set('more!',1); -//$c->set('more!', array($c->get('more!'))); -//$c->save(); -//$c->delete(); - - diff --git a/modules/DataFiles/Browsers.php b/modules/DataFiles/Browsers.php deleted file mode 100644 index 96a379fb4e..0000000000 --- a/modules/DataFiles/Browsers.php +++ /dev/null @@ -1,59 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_UserSettings - */ - -/** - * Browser list. - * If you want to add a new entry, please email us at hello at piwik.org - * - */ -if(!isset($GLOBALS['Piwik_BrowserList'] )) -{ - $GLOBALS['Piwik_BrowserList'] = array( - 'msie' => 'IE', - 'microsoft internet explorer' => 'IE', - 'internet explorer' => 'IE', - 'netscape6' => 'NS', - 'netscape' => 'NS', - 'galeon' => 'GA', - 'phoenix' => 'PX', - 'firefox' => 'FF', - 'mozilla firebird' => 'FB', - 'firebird' => 'FB', - 'seamonkey' => 'SM', - 'chimera' => 'CH', - 'camino' => 'CA', - 'safari' => 'SF', - 'k-meleon' => 'KM', - 'mozilla' => 'MO', - 'opera' => 'OP', - 'konqueror' => 'KO', - 'icab' => 'IC', - 'lynx' => 'LX', - 'links' => 'LI', - 'ncsa mosaic' => 'MC', - 'amaya' => 'AM', - 'omniweb' => 'OW', - 'hotjava' => 'HJ', - 'browsex' => 'BX', - 'amigavoyager' => 'AV', - 'amiga-aweb' => 'AW', - 'ibrowse' => 'IB', - 'unknown' => 'UNK' - ); - - - $GLOBALS['Piwik_BrowserList_IdToLabel'] - = array_map('ucwords',array_flip($GLOBALS['Piwik_BrowserList'])); - - $GLOBALS['Piwik_BrowserList_IdToShortLabel'] = $GLOBALS['Piwik_BrowserList_IdToLabel']; - $GLOBALS['Piwik_BrowserList_IdToShortLabel']['IE'] = "IE"; - $GLOBALS['Piwik_BrowserList_IdToShortLabel']['FB'] = "Firebird"; -} diff --git a/modules/DataFiles/Countries.php b/modules/DataFiles/Countries.php deleted file mode 100644 index 85c46713b4..0000000000 --- a/modules/DataFiles/Countries.php +++ /dev/null @@ -1,240 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_UserCountry - */ - -/** - * Country code and continent database. - * If you want to add a new entry, please email us at hello at piwik.org - * - */ -if(!isset($GLOBALS['Piwik_CountryList'])) -{ - $GLOBALS['Piwik_CountryList'] = array( - 'xx' => array('unk'), - 'ac' => array('afr'), - 'ad' => array('eur'), - 'ae' => array('asi'), - 'af' => array('asi'), - 'ag' => array('ams'), - 'ai' => array('ams'), - 'al' => array('eur'), - 'am' => array('asi'), - 'an' => array('ams'), - 'ao' => array('afr'), - 'aq' => array('aut'), - 'ar' => array('ams'), - 'as' => array('oce'), - 'at' => array('eur'), - 'au' => array('oce'), - 'aw' => array('ams'), - 'az' => array('asi'), - 'ba' => array('eur'), - 'bb' => array('ams'), - 'bd' => array('asi'), - 'be' => array('eur'), - 'bf' => array('afr'), - 'bg' => array('eur'), - 'bh' => array('asi'), - 'bi' => array('afr'), - 'bj' => array('afr'), - 'bm' => array('ams'), - 'bn' => array('asi'), - 'bo' => array('ams'), - 'br' => array('ams'), - 'bs' => array('ams'), - 'bt' => array('asi'), - 'bw' => array('afr'), - 'by' => array('eur'), - 'bz' => array('ams'), - 'ca' => array('amn'), - 'cc' => array('oce'), - 'cd' => array('afr'), - 'cf' => array('afr'), - 'cg' => array('afr'), - 'ch' => array('eur'), - 'ci' => array('afr'), - 'ck' => array('asi'), - 'cl' => array('ams'), - 'cm' => array('afr'), - 'cn' => array('asi'), - 'co' => array('ams'), - 'cs' => array('eur'), - 'cr' => array('ams'), - 'cu' => array('ams'), - 'cv' => array('afr'), - 'cy' => array('eur'), - 'cz' => array('eur'), - 'de' => array('eur'), - 'dj' => array('afr'), - 'dk' => array('eur'), - 'dm' => array('ams'), - 'do' => array('ams'), - 'dz' => array('afr'), - 'ec' => array('ams'), - 'ee' => array('eur'), - 'eg' => array('afr'), - 'eh' => array('afr'), - 'er' => array('afr'), - 'es' => array('eur'), - 'et' => array('afr'), - 'fi' => array('eur'), - 'fj' => array('oce'), - 'fk' => array('ams'), - 'fm' => array('oce'), - 'fr' => array('eur'), - 'ga' => array('afr'), - 'gb' => array('eur'), - 'gd' => array('ams'), - 'ge' => array('asi'), - 'gf' => array('ams'), - 'gg' => array('eur'), - 'gh' => array('afr'), - 'gi' => array('afr'), - 'gl' => array('amn'), - 'gm' => array('afr'), - 'gn' => array('afr'), - 'gp' => array('ams'), - 'gq' => array('afr'), - 'gr' => array('eur'), - 'gs' => array('eur'), - 'gt' => array('ams'), - 'gw' => array('afr'), - 'gy' => array('ams'), - 'hk' => array('asi'), - 'hn' => array('ams'), - 'hr' => array('eur'), - 'ht' => array('ams'), - 'hu' => array('eur'), - 'id' => array('asi'), - 'ie' => array('eur'), - 'il' => array('asi'), - 'in' => array('asi'), - 'iq' => array('asi'), - 'ir' => array('asi'), - 'is' => array('eur'), - 'it' => array('eur'), - 'jm' => array('ams'), - 'jo' => array('asi'), - 'jp' => array('asi'), - 'ke' => array('afr'), - 'kg' => array('asi'), - 'kh' => array('asi'), - 'ki' => array('oce'), - 'km' => array('afr'), - 'kp' => array('asi'), - 'kr' => array('asi'), - 'kw' => array('asi'), - 'ky' => array('ams'), - 'kz' => array('asi'), - 'la' => array('asi'), - 'lb' => array('asi'), - 'li' => array('eur'), - 'lk' => array('asi'), - 'lr' => array('afr'), - 'ls' => array('afr'), - 'lt' => array('eur'), - 'lu' => array('eur'), - 'lv' => array('eur'), - 'ly' => array('afr'), - 'ma' => array('afr'), - 'mc' => array('eur'), - 'md' => array('eur'), - 'mg' => array('afr'), - 'mh' => array('oce'), - 'mk' => array('eur'), - 'ml' => array('afr'), - 'mm' => array('asi'), - 'mn' => array('asi'), - 'mo' => array('asi'), - 'mq' => array('ams'), - 'mr' => array('afr'), - 'mt' => array('eur'), - 'mu' => array('afr'), - 'mv' => array('asi'), - 'mw' => array('afr'), - 'mx' => array('ams'), - 'my' => array('asi'), - 'mz' => array('afr'), - 'na' => array('afr'), - 'nc' => array('oce'), - 'ne' => array('afr'), - 'ng' => array('afr'), - 'ni' => array('ams'), - 'nl' => array('eur'), - 'no' => array('eur'), - 'np' => array('asi'), - 'nr' => array('oce'), - 'nz' => array('oce'), - 'om' => array('asi'), - 'pa' => array('ams'), - 'pe' => array('ams'), - 'pf' => array('oce'), - 'pg' => array('oce'), - 'ph' => array('asi'), - 'pk' => array('asi'), - 'pl' => array('eur'), - 'pm' => array('amn'), - 'pr' => array('ams'), - 'pt' => array('eur'), - 'pw' => array('oce'), - 'py' => array('ams'), - 'qa' => array('asi'), - 're' => array('afr'), - 'ro' => array('eur'), - 'ru' => array('asi'), - 'rs' => array('asi'), - 'rw' => array('afr'), - 'sa' => array('asi'), - 'sb' => array('oce'), - 'sc' => array('afr'), - 'sd' => array('afr'), - 'se' => array('eur'), - 'sg' => array('asi'), - 'si' => array('eur'), - 'sk' => array('eur'), - 'sl' => array('afr'), - 'sm' => array('eur'), - 'sn' => array('afr'), - 'so' => array('afr'), - 'sr' => array('ams'), - 'sv' => array('ams'), - 'sy' => array('asi'), - 'sz' => array('afr'), - 'td' => array('afr'), - 'tg' => array('afr'), - 'th' => array('asi'), - 'tj' => array('asi'), - 'tm' => array('asi'), - 'tn' => array('afr'), - 'to' => array('oce'), - 'tp' => array('oce'), - 'tr' => array('eur'), - 'tt' => array('ams'), - 'tw' => array('asi'), - 'tz' => array('afr'), - 'ua' => array('eur'), - 'ug' => array('afr'), - 'uk' => array('eur'), - 'us' => array('amn'), - 'uy' => array('ams'), - 'uz' => array('asi'), - 'va' => array('eur'), - 've' => array('ams'), - 'vn' => array('asi'), - 'vu' => array('oce'), - 'wf' => array('oce'), - 'ye' => array('asi'), - 'yu' => array('eur'), - 'za' => array('afr'), - 'zm' => array('afr'), - 'zw' => array('afr'), - ); -} - diff --git a/modules/DataFiles/OS.php b/modules/DataFiles/OS.php deleted file mode 100644 index 9bce88e7bc..0000000000 --- a/modules/DataFiles/OS.php +++ /dev/null @@ -1,86 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_UserSettings - */ - -/** - * Operating systems database. - * If you want to add a new entry, please email us at hello at piwik.org - * - */ -if(!isset($GLOBALS['Piwik_Oslist'])) -{ - $GLOBALS['Piwik_Oslist'] = array( - 'Nintendo Wii' => 'WII', - 'PlayStation Portable' => 'PSP', - 'PLAYSTATION 3' => 'PS3', - 'Windows NT 6.0' => 'WVI', - 'Windows Vista' => 'WVI', - 'Windows NT 5.2' => 'WS3', - 'Windows Server 2003' => 'WS3', - 'Windows NT 5.1' => 'WXP', - 'Windows XP' => 'WXP', - 'Win98' => 'W98', - 'Windows 98' => 'W98', - 'Windows NT 5.0' => 'W2K', - 'Windows 2000' => 'W2K', - 'Windows NT 4.0' => 'WNT', - 'WinNT' => 'WNT', - 'Windows NT' => 'WNT', - 'Win 9x 4.90' => 'WME', - 'Win 9x 4.90' => 'WME', - 'Windows Me' => 'WME', - 'Win32' => 'W95', - 'Win95' => 'W95', - 'Windows 95' => 'W95', - 'Mac_PowerPC' => 'MAC', - 'Mac PPC' => 'MAC', - 'PPC' => 'MAC', - 'Mac PowerPC' => 'MAC', - 'Mac OS' => 'MAC', - 'Linux' => 'LIN', - 'SunOS' => 'SOS', - 'FreeBSD' => 'BSD', - 'AIX' => 'AIX', - 'IRIX' => 'IRI', - 'HP-UX' => 'HPX', - 'OS/2' => 'OS2', - 'NetBSD' => 'NBS', - 'Unknown' => 'XXX' - ); - - - $GLOBALS['Piwik_Oslist_IdToLabel'] = array_flip($GLOBALS['Piwik_Oslist']); - - $GLOBALS['Piwik_Oslist_IdToShortLabel'] = array( - 'PS3' => 'PS3', - 'PSP' => 'PSP', - 'WII' => 'WII', - 'WVI' => 'Win Vista', - 'WS3' => 'Win S2003', - 'WXP' => 'Win XP', - 'W98' => 'Win 98', - 'W2K' => 'Win 2000', - 'WNT' => 'Win NT', - 'WME' => 'Win Me', - 'W95' => 'Win 95', - 'WCE' => 'Win CE', - 'MAC' => 'Mac OS', - 'LIN' => 'Linux', - 'INC' => 'Inconnu', - 'SOS' => 'SunOS', - 'BSD' => 'FreeBSD', - 'AIX' => 'AIX', - 'IRI' => 'IRIX', - 'HPX' => 'HPX', - 'OS2' => 'OS/2', - 'NBS' => 'NetBSD', - 'XXX' => 'Unknown', - ); -} diff --git a/modules/DataFiles/SearchEngines.php b/modules/DataFiles/SearchEngines.php deleted file mode 100644 index dbcac01a2b..0000000000 --- a/modules/DataFiles/SearchEngines.php +++ /dev/null @@ -1,1080 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_Referers - */ -/** - * Search Engine database - * - * ====================================== - * HOW TO ADD A SEARCH ENGINE TO THE LIST - * ====================================== - * If you want to add a new entry, please email us the information + icon at hello at piwik.org - * - * Detail of a line: - * Url => array( SearchEngineName, VariableKeyword, [charset used by the search engine]) - * - * The main search engine URL has to be at the top of the list for the given search Engine. - * - * You can add new search engines icons by adding the icon - * in the plugins/Referers/images/SearchEngines directory - * using the format "mainSearchEngineUrl.png". Example: www.google.com.png - * - * - */ -if(!isset($GLOBALS['Piwik_SearchEngines'] )) -{ - $GLOBALS['Piwik_SearchEngines'] = array( - - //" " => array(" ", " " [, " "]), - - // 1 - "1.cz" => array("1.cz", "q", "iso-8859-2"), - "www.1.cz" => array("1.cz", "q", "iso-8859-2"), - - // 1und1 - "portal.1und1.de" => array("1und1", "search"), - - // 3271 - "nmsearch.3721.com" => array("3271", "p"), - "seek.3721.com" => array("3271", "p"), - - // A9 - "www.a9.com" => array("A9", ""), - "a9.com" => array("A9", ""), - - // Abacho - "search.abacho.com" => array("Abacho", "q"), - - // about - "search.about.com" => array("About", "terms"), - - //Acoon - "www.acoon.de" => array("Acoon", "begriff"), - - //Acont - "acont.de" => array("Acont", "query"), - - //Alexa - "www.alexa.com" => array("Alexa", "q"), - "alexa.com" => array("Alexa", "q"), - - //Alice Adsl - "rechercher.aliceadsl.fr" => array("Alice Adsl", "qs"), - "search.alice.it" => array("Alice (Virgilio)", "qt"), - - //Allesklar - "www.allesklar.de" => array("Allesklar", "words"), - - // AllTheWeb - "www.alltheweb.com" => array("AllTheWeb", "q"), - - // all.by - "all.by" => array("All.by", "query"), - - // Altavista - "www.altavista.com" => array("AltaVista", "q"), - "listings.altavista.com" => array("AltaVista", "q"), - "www.altavista.de" => array("AltaVista", "q"), - "altavista.fr" => array("AltaVista", "q"), - "de.altavista.com" => array("AltaVista", "q"), - "fr.altavista.com" => array("AltaVista", "q"), - "es.altavista.com" => array("AltaVista", "q"), - "www.altavista.fr" => array("AltaVista", "q"), - "search.altavista.com" => array("AltaVista", "q"), - "search.fr.altavista.com" => array("AltaVista", "q"), - "se.altavista.com" => array("AltaVista", "q"), - "be-nl.altavista.com" => array("AltaVista", "q"), - "be-fr.altavista.com" => array("AltaVista", "q"), - "it.altavista.com" => array("AltaVista", "q"), - "us.altavista.com" => array("AltaVista", "q"), - "nl.altavista.com" => array("Altavista", "q"), - "ch.altavista.com" => array("AltaVista", "q"), - - // APOLLO7 - "www.apollo7.de" => array("Apollo7", "query"), - "apollo7.de" => array("Apollo7", "query"), - - // AOL - "search.aol.com" => array("AOL", "query"), - "aolsearch.aol.com" => array("AOL", "query"), - "www.aolrecherche.aol.fr" => array("AOL", "q"), - "www.aolrecherches.aol.fr" => array("AOL", "query"), - "www.aolimages.aol.fr" => array("AOL", "query"), - "www.recherche.aol.fr" => array("AOL", "q"), - "aolsearcht.aol.com" => array("AOL", "query"), - "find.web.aol.com" => array("AOL", "query"), - "recherche.aol.ca" => array("AOL", "query"), - "aolsearch.aol.co.uk" => array("AOL", "query"), - "search.aol.co.uk" => array("AOL", "query"), - "aolrecherche.aol.fr" => array("AOL", "q"), - "sucheaol.aol.de" => array("AOL", "q"), - "suche.aol.de" => array("AOL", "q"), - "suche.aolsvc.de" => array("AOL", "q"), - - "aolbusqueda.aol.com.mx" => array("AOL", "query"), - - // Aport - "sm.aport.ru" => array("Aport", "r"), - - // Arcor - "www.arcor.de" => array("Arcor", "Keywords"), - - // Arianna (Libero.it) - "arianna.libero.it" => array("Arianna", "query"), - - // Ask - "www.ask.com" => array("Ask", "ask"), - "web.ask.com" => array("Ask", "ask"), - "www.ask.co.uk" => array("Ask", "q"), - "uk.ask.com" => array("Ask", "q"), - "fr.ask.com" => array("Ask", "q"), - "de.ask.com" => array("Ask", "q"), - "es.ask.com" => array("Ask", "q"), - "it.ask.com" => array("Ask", "q"), - "nl.ask.com" => array("Ask", "q"), - "ask.jp" => array("Ask", "q"), - - // Atlas - "search.atlas.cz" => array("Atlas", "q", "windows-1250"), - - // Austronaut - "www2.austronaut.at" => array("Austronaut", "begriff"), - - // Baidu - "www.baidu.com" => array("Baidu", "wd"), - "www1.baidu.com" => array("Baidu", "wd"), - - // BBC - "search.bbc.co.uk" => array("BBC", "q"), - - // Bellnet - "www.suchmaschine.com" => array("Bellnet", "suchstr"), - - // Biglobe - "cgi.search.biglobe.ne.jp" => array("Biglobe", "q"), - - // Bild - "www.bild.t-online.de" => array("Bild.de (enhanced by Google)", "query"), - - //Blogdigger - "www.blogdigger.com" => array("Blogdigger","q"), - - //Bloglines - "www.bloglines.com" => array("Bloglines","q"), - - //Blogpulse - "www.blogpulse.com" => array("Blogpulse","query"), - - //Bluewin - "search.bluewin.ch" => array("Bluewin","query"), - - // Caloweb - "www.caloweb.de" => array("Caloweb", "q"), - - // Cegetel (Google) - "www.cegetel.net" => array("Cegetel (Google)", "q"), - - // Centrum - "fulltext.centrum.cz" => array("Centrum", "q", "windows-1250"), - "morfeo.centrum.cz" => array("Centrum", "q", "windows-1250"), - "search.centrum.cz" => array("Centrum", "q", "windows-1250"), - - // Chello - "www.chello.fr" => array("Chello", "q1"), - - // Club Internet - "recherche.club-internet.fr" => array("Club Internet", "q"), - - // Comcast - "www.comcast.net" => array("Comcast", "query"), - - // Comet systems - "search.cometsystems.com" => array("CometSystems", "q"), - - // Compuserve - "suche.compuserve.de" => array("Compuserve.de (Powered by Google)", "q"), - "websearch.cs.com" => array("Compuserve.com (Enhanced by Google)", "query"), - - // Copernic - "metaresults.copernic.com" => array("Copernic", " "), - - // Crossbot - "www.crossbot.de" => array("Crossbot", "q"), - - // DasOertliche - "www.dasoertliche.de" => array("DasOertliche", "kw"), - - // DasTelefonbuch - "www.4call.dastelefonbuch.de" => array("DasTelefonbuch", "kw"), - - // Defind.de - "suche.defind.de" => array("Defind.de", "search"), - - // Deskfeeds - "www.deskfeeds.com" => array("Deskfeeds", "sx"), - - // Dino - "www.dino-online.de" => array("Dino", "query"), - - // dir.com - "fr.dir.com" => array("dir.com", "req"), - - // dmoz - "dmoz.org" => array("dmoz", "search"), - "editors.dmoz.org" => array("dmoz", "search"), - "search.dmoz.org" => array("dmoz", "search"), - "www.dmoz.org" => array("dmoz", "search"), - - // Dogpile - "search.dogpile.com" => array("Dogpile", "q"), - "nbci.dogpile.com" => array("Dogpile", "q"), - - // earthlink - "search.earthlink.net" => array("Earthlink", "q"), - - // Eniro - "www.eniro.se" => array("Eniro", "q"), - - // Espotting - "affiliate.espotting.fr" => array("Espotting", "keyword"), - - // Eudip - "www.eudip.com" => array("Eudip", " "), - - // Eurip - "www.eurip.com" => array("Eurip", "q"), - - // Euroseek - "www.euroseek.com" => array("Euroseek", "string"), - - // Excite - "www.excite.it" => array("Excite", "q"), - "msxml.excite.com" => array("Excite", "qkw"), - "www.excite.fr" => array("Excite", "search"), - - // Exalead - "www.exalead.fr" => array("Exalead", "q"), - "www.exalead.com" => array("Exalead", "q"), - - // eo - "eo.st" => array("eo", "q"), - - // Feedminer - "www.feedminer.com" => array("Feedminer", "q"), - - // Feedster - "www.feedster.com" => array("Feedster", ""), - - // Francite - "recherche.francite.com" => array("Francite", "name"), - "antisearch.francite.com" => array("Francite", "KEYWORDS"), - - // Fireball - "suche.fireball.de" => array("Fireball", "query"), - - - // Firstfind - "www.firstsfind.com" => array("Firstsfind", "qry"), - - // Fixsuche - "www.fixsuche.de" => array("Fixsuche", "q"), - - // Flix - "www.flix.de" => array("Flix.de", "keyword"), - - // Free - "search.free.fr" => array("Free", "q"), - "search1-2.free.fr" => array("Free", "q"), - "search1-1.free.fr" => array("Free", "q"), - - // Freenet - "suche.freenet.de" => array("Freenet", "query"), - - //Froogle - "froogle.google.com" => array("Google (Froogle)", "q"), - "froogle.google.de" => array("Google (Froogle)", "q"), - "froogle.google.co.uk" => array("Google (Froogle)", "q"), - - //GAIS - "gais.cs.ccu.edu.tw" => array("GAIS)", "query"), - - // Gigablast - "www.gigablast.com" => array("Gigablast", "q"), - "blogs.gigablast.com" => array("Gigablast (Blogs)", "q"), - "travel.gigablast.com" => array("Gigablast (Travel)", "q"), - "dir.gigablast.com" => array("Gigablast (Directory)", "q"), - "gov.gigablast.com" => array("Gigablast (Gov)", "q"), - - // GMX - "suche.gmx.net" => array("GMX", "su"), - "www.gmx.net" => array("GMX", "su"), - - // goo - "search.goo.ne.jp" => array("goo", "mt"), - "ocnsearch.goo.ne.jp" => array("goo", "mt"), - - - // Google - "www.google.com" => array("Google", "q"), - "gogole.fr" => array("Google", "q"), - "www.gogole.fr" => array("Google", "q"), - "wwwgoogle.fr" => array("Google", "q"), - "ww.google.fr" => array("Google", "q"), - "w.google.fr" => array("Google", "q"), - "www.google.fr" => array("Google", "q"), - "www.google.fr." => array("Google", "q"), - "google.fr" => array("Google", "q"), - "www2.google.com" => array("Google", "q"), - "w.google.com" => array("Google", "q"), - "ww.google.com" => array("Google", "q"), - "wwwgoogle.com" => array("Google", "q"), - "www.gogole.com" => array("Google", "q"), - "www.gppgle.com" => array("Google", "q"), - "go.google.com" => array("Google", "q"), - "www.google.ae" => array("Google", "q"), - "www.google.as" => array("Google", "q"), - "www.google.at" => array("Google", "q"), - "wwwgoogle.at" => array("Google", "q"), - "ww.google.at" => array("Google", "q"), - "w.google.at" => array("Google", "q"), - "www.google.az" => array("Google", "q"), - "www.google.be" => array("Google", "q"), - "www.google.bg" => array("Google", "q"), - "www.google.ba" => array("Google", "q"), - "google.bg" => array("Google", "q"), - "www.google.bi" => array("Google", "q"), - "www.google.ca" => array("Google", "q"), - "ww.google.ca" => array("Google", "q"), - "w.google.ca" => array("Google", "q"), - "www.google.cc" => array("Google", "q"), - "www.google.cd" => array("Google", "q"), - "www.google.cg" => array("Google", "q"), - "www.google.ch" => array("Google", "q"), - "ww.google.ch" => array("Google", "q"), - "w.google.ch" => array("Google", "q"), - "www.google.ci" => array("Google", "q"), - "www.google.cl" => array("Google", "q"), - "www.google.cn" => array("Google", "q"), - "www.google.co" => array("Google", "q"), - "www.google.cz" => array("Google", "q"), - "wwwgoogle.cz" => array("Google", "q"), - "www.google.de" => array("Google", "q"), - "ww.google.de" => array("Google", "q"), - "w.google.de" => array("Google", "q"), - "wwwgoogle.de" => array("Google", "q"), - "www.googleearth.de" => array("Google", "q"), - "googleearth.de" => array("Google", "q"), - "google.gr" => array("Google", "q"), - "google.hr" => array("Google", "q"), - "www.google.dj" => array("Google", "q"), - "www.google.dk" => array("Google", "q"), - "www.google.es" => array("Google", "q"), - "www.google.fi" => array("Google", "q"), - "www.google.fm" => array("Google", "q"), - "www.google.gg" => array("Google", "q"), - "www.googel.fi" => array("Google", "q"), - "www.googleearth.fr" => array("Google", "q"), - "www.google.gl" => array("Google", "q"), - "www.google.gm" => array("Google", "q"), - "www.google.gr" => array("Google", "q"), - "www.google.hn" => array("Google", "q"), - "www.google.hr" => array("Google", "q"), - "www.google.hu" => array("Google", "q"), - "www.google.ie" => array("Google", "q"), - "www.google.is" => array("Google", "q"), - "www.google.it" => array("Google", "q"), - "www.google.jo" => array("Google", "q"), - "www.google.kz" => array("Google", "q"), - "www.google.li" => array("Google", "q"), - "www.google.lt" => array("Google", "q"), - "www.google.lu" => array("Google", "q"), - "www.google.lv" => array("Google", "q"), - "www.google.ms" => array("Google", "q"), - "www.google.mu" => array("Google", "q"), - "www.google.mw" => array("Google", "q"), - "www.google.md" => array("Google", "q"), - "www.google.nl" => array("Google", "q"), - "www.google.no" => array("Google", "q"), - "www.google.pl" => array("Google", "q"), - "www.google.sk" => array("Google", "q"), - "www.google.pn" => array("Google", "q"), - "www.google.pt" => array("Google", "q"), - "www.google.dk" => array("Google", "q"), - "www.google.ro" => array("Google", "q"), - "www.google.ru" => array("Google", "q"), - "www.google.rw" => array("Google", "q"), - "www.google.se" => array("Google", "q"), - "www.google.sn" => array("Google", "q"), - "www.google.sh" => array("Google", "q"), - "www.google.si" => array("Google", "q"), - "www.google.sm" => array("Google", "q"), - "www.google.td" => array("Google", "q"), - "www.google.tt" => array("Google", "q"), - "www.google.uz" => array("Google", "q"), - "www.google.vg" => array("Google", "q"), - "www.google.com.ar" => array("Google", "q"), - "www.google.com.au" => array("Google", "q"), - "www.google.com.bo" => array("Google", "q"), - "www.google.com.br" => array("Google", "q"), - "www.google.com.co" => array("Google", "q"), - "www.google.com.cu" => array("Google", "q"), - "www.google.com.ec" => array("Google", "q"), - "www.google.com.eg" => array("Google", "q"), - "www.google.com.do" => array("Google", "q"), - "www.google.com.fj" => array("Google", "q"), - "www.google.com.gr" => array("Google", "q"), - "www.google.com.gt" => array("Google", "q"), - "www.google.com.hk" => array("Google", "q"), - "www.google.com.ly" => array("Google", "q"), - "www.google.com.mt" => array("Google", "q"), - "www.google.com.mx" => array("Google", "q"), - "www.google.com.my" => array("Google", "q"), - "www.google.com.nf" => array("Google", "q"), - "www.google.com.ni" => array("Google", "q"), - "www.google.com.np" => array("Google", "q"), - "www.google.com.pa" => array("Google", "q"), - "www.google.com.pe" => array("Google", "q"), - "www.google.com.ph" => array("Google", "q"), - "www.google.com.pk" => array("Google", "q"), - "www.google.com.pl" => array("Google", "q"), - "www.google.com.pr" => array("Google", "q"), - "www.google.com.py" => array("Google", "q"), - "www.google.com.qa" => array("Google", "q"), - "www.google.com.om" => array("Google", "q"), - "www.google.com.ru" => array("Google", "q"), - "www.google.com.sg" => array("Google", "q"), - "www.google.com.sa" => array("Google", "q"), - "www.google.com.sv" => array("Google", "q"), - "www.google.com.tr" => array("Google", "q"), - "www.google.com.tw" => array("Google", "q"), - "www.google.com.ua" => array("Google", "q"), - "www.google.com.uy" => array("Google", "q"), - "www.google.com.vc" => array("Google", "q"), - "www.google.com.vn" => array("Google", "q"), - "www.google.co.cr" => array("Google", "q"), - "www.google.co.gg" => array("Google", "q"), - "www.google.co.hu" => array("Google", "q"), - "www.google.co.id" => array("Google", "q"), - "www.google.co.il" => array("Google", "q"), - "www.google.co.in" => array("Google", "q"), - "www.google.co.je" => array("Google", "q"), - "www.google.co.jp" => array("Google", "q"), - "www.google.co.ls" => array("Google", "q"), - "www.google.co.ke" => array("Google", "q"), - "www.google.co.kr" => array("Google", "q"), - "www.google.co.nz" => array("Google", "q"), - "www.google.co.th" => array("Google", "q"), - "www.google.co.uk" => array("Google", "q"), - "www.google.co.ve" => array("Google", "q"), - "www.google.co.za" => array("Google", "q"), - "www.google.co.ma" => array("Google", "q"), - "www.goggle.com" => array("Google", "q"), - - - // Powered by Google - "www.charter.net" => array("Google", "q"), - "brisbane.t-online.de" => array("Google", "q"), - "miportal.bellsouth.net" => array("Google", "string"), - "home.bellsouth.net" => array("Google", "string"), - "pesquisa.clix.pt" => array("Google", "q"), - "google.startsiden.no" => array("Google", "q"), - "google.startpagina.nl" => array("Google", "q"), - "search.peoplepc.com" => array("Google", "q"), - "www.google.interia.pl" => array("Google", "q"), - "buscador.terra.es" => array("Google", "query"), - "buscador.terra.cl" => array("Google", "query"), - "buscador.terra.com.br" => array("Google", "query"), - "www.icq.com" => array("Google", "q"), - "www.adelphia.net" => array("Google", "q"), - "so.qq.com" => array("Google", "word"), - "misc.skynet.be" => array("Google", "keywords"), - "www.start.no" => array("Google", "q"), - "verden.abcsok.no" => array("Google", "q"), - "search.sweetim.com" => array("Google", "q"), - - - //Google Blogsearch - "blogsearch.google.com" => array("Google Blogsearch", "q"), - "blogsearch.google.de" => array("Google Blogsearch", "q"), - "blogsearch.google.fr" => array("Google Blogsearch", "q"), - "blogsearch.google.co.uk" => array("Google Blogsearch", "q"), - "blogsearch.google.it" => array("Google Blogsearch", "q"), - "blogsearch.google.net" => array("Google Blogsearch", "q"), - "blogsearch.google.es" => array("Google Blogsearch", "q"), - "blogsearch.google.ru" => array("Google Blogsearch", "q"), - "blogsearch.google.be" => array("Google Blogsearch", "q"), - "blogsearch.google.nl" => array("Google Blogsearch", "q"), - "blogsearch.google.at" => array("Google Blogsearch", "q"), - "blogsearch.google.ch" => array("Google Blogsearch", "q"), - "blogsearch.google.pl" => array("Google Blogsearch", "q"), - - - // Google translation - "translate.google.com" => array("Google Translations", "q"), - - // Google Directory - "directory.google.com" => array("Google Directory", " "), - - // Google Images - "images.google.fr" => array("Google Images", "q"), - "images.google.be" => array("Google Images", "q"), - "images.google.ca" => array("Google Images", "q"), - "images.google.co.uk" => array("Google Images", "q"), - "images.google.de" => array("Google Images", "q"), - "images.google.it" => array("Google Images", "q"), - "images.google.at" => array("Google Images", "q"), - "images.google.bg" => array("Google Images", "q"), - "images.google.ch" => array("Google Images", "q"), - "images.google.ci" => array("Google Images", "q"), - "images.google.com.au" => array("Google Images", "q"), - "images.google.com.cu" => array("Google Images", "q"), - "images.google.co.id" => array("Google Images", "q"), - "images.google.co.il" => array("Google Images", "q"), - "images.google.co.in" => array("Google Images", "q"), - "images.google.co.jp" => array("Google Images", "q"), - "images.google.co.hu" => array("Google Images", "q"), - "images.google.co.kr" => array("Google Images", "q"), - "images.google.co.nz" => array("Google Images", "q"), - "images.google.co.th" => array("Google Images", "q"), - "images.google.co.tw" => array("Google Images", "q"), - "images.google.co.ve" => array("Google Images", "q"), - "images.google.com.ar" => array("Google Images", "q"), - "images.google.com.br" => array("Google Images", "q"), - "images.google.com.cu" => array("Google Images", "q"), - "images.google.com.do" => array("Google Images", "q"), - "images.google.com.gr" => array("Google Images", "q"), - "images.google.com.hk" => array("Google Images", "q"), - "images.google.com.mx" => array("Google Images", "q"), - "images.google.com.my" => array("Google Images", "q"), - "images.google.com.pe" => array("Google Images", "q"), - "images.google.com.tr" => array("Google Images", "q"), - "images.google.com.tw" => array("Google Images", "q"), - "images.google.com.ua" => array("Google Images", "q"), - "images.google.com.vn" => array("Google Images", "q"), - "images.google.dk" => array("Google Images", "q"), - "images.google.es" => array("Google Images", "q"), - "images.google.fi" => array("Google Images", "q"), - "images.google.gg" => array("Google Images", "q"), - "images.google.gr" => array("Google Images", "q"), - "images.google.it" => array("Google Images", "q"), - "images.google.ms" => array("Google Images", "q"), - "images.google.nl" => array("Google Images", "q"), - "images.google.no" => array("Google Images", "q"), - "images.google.pl" => array("Google Images", "q"), - "images.google.pt" => array("Google Images", "q"), - "images.google.ro" => array("Google Images", "q"), - "images.google.ru" => array("Google Images", "q"), - "images.google.se" => array("Google Images", "q"), - "images.google.sk" => array("Google Images", "q"), - "images.google.com" => array("Google Images", "q"), - - // Google News - "news.google.com" => array("Google News", "q"), - "news.google.se" => array("Google News", "q"), - "news.google.com" => array("Google News", "q"), - "news.google.es" => array("Google News", "q"), - "news.google.ch" => array("Google News", "q"), - "news.google.lt" => array("Google News", "q"), - "news.google.ie" => array("Google News", "q"), - "news.google.de" => array("Google News", "q"), - "news.google.cl" => array("Google News", "q"), - "news.google.com.ar" => array("Google News", "q"), - "news.google.fr" => array("Google News", "q"), - "news.google.ca" => array("Google News", "q"), - "news.google.co.uk" => array("Google News", "q"), - "news.google.co.jp" => array("Google News", "q"), - "news.google.com.pe" => array("Google News", "q"), - "news.google.com.au" => array("Google News", "q"), - "news.google.com.mx" => array("Google News", "q"), - "news.google.com.hk" => array("Google News", "q"), - "news.google.co.in" => array("Google News", "q"), - "news.google.at" => array("Google News", "q"), - "news.google.com.tw" => array("Google News", "q"), - "news.google.com.co" => array("Google News", "q"), - "news.google.co.ve" => array("Google News", "q"), - "news.google.lu" => array("Google News", "q"), - "news.google.com.ly" => array("Google News", "q"), - "news.google.it" => array("Google News", "q"), - "news.google.sm" => array("Google News", "q"), - - // Goyellow.de - "www.goyellow.de" => array("GoYellow.de", "MDN"), - - // HighBeam - "www.highbeam.com" => array("HighBeam", "Q"), - - // Hit-Parade - "recherche.hit-parade.com" => array("Hit-Parade", "p7"), - "class.hit-parade.com" => array("Hit-Parade", "p7"), - - // Hotbot via Lycos - "hotbot.lycos.com" => array("Hotbot (Lycos)", "query"), - "search.hotbot.de" => array("Hotbot", "query"), - "search.hotbot.fr" => array("Hotbot", "query"), - "www.hotbot.com" => array("Hotbot", "query"), - - // 1stekeuze - "zoek.1stekeuze.nl" => array("1stekeuze", "terms"), - - // Infoseek - "search.www.infoseek.co.jp" => array("Infoseek", "qt"), - - // Icerocket - "blogs.icerocket.com" => array("Icerocket", "qt"), - - // ICQ - "www.icq.com" => array("ICQ", "q"), - "search.icq.com" => array("ICQ", "q"), - - // Ilse - "spsearch.ilse.nl" => array("Startpagina", "search_for"), - "be.ilse.nl" => array("Ilse BE", "query"), - "search.ilse.nl" => array("Ilse NL", "search_for"), - - // Iwon - "search.iwon.com" => array("Iwon", "searchfor"), - - // Ixquick - "ixquick.com" => array("Ixquick", "query"), - "www.eu.ixquick.com" => array("Ixquick", "query"), - "us.ixquick.com" => array("Ixquick", "query"), - "s1.us.ixquick.com" => array("Ixquick", "query"), - "s2.us.ixquick.com" => array("Ixquick", "query"), - "s3.us.ixquick.com" => array("Ixquick", "query"), - "s4.us.ixquick.com" => array("Ixquick", "query"), - "s5.us.ixquick.com" => array("Ixquick", "query"), - "eu.ixquick.com" => array("Ixquick","query"), - - // Jyxo - "jyxo.cz" => array("Jyxo", "q"), - - // Jungle Spider - "www.jungle-spider.de" => array("Jungle Spider", "qry"), - - // Kartoo - "kartoo.com" => array("Kartoo", ""), - "kartoo.de" => array("Kartoo", ""), - "kartoo.fr" => array("Kartoo", ""), - - - // Kataweb - "www.kataweb.it" => array("Kataweb", "q"), - - // Klug suchen - "www.klug-suchen.de" => array("Klug suchen!", "query"), - - // La Toile Du Québec via Google - "google.canoe.com" => array("La Toile Du Québec (Google)", "q"), - "www.toile.com" => array("La Toile Du Québec (Google)", "q"), - "web.toile.com" => array("La Toile Du Québec (Google)", "q"), - - // La Toile Du Québec - "recherche.toile.qc.ca" => array("La Toile Du Québec", "query"), - - // Live.com - "www.live.com" => array("Live", "q"), - "beta.search.live.com" => array("Live", "q"), - "search.live.com" => array("Live", "q"), - "g.msn.com" => array("Live", " "), - - // Looksmart - "www.looksmart.com" => array("Looksmart", "key"), - - // Lycos - "search.lycos.com" => array("Lycos", "query"), - "vachercher.lycos.fr" => array("Lycos", "query"), - "www.lycos.fr" => array("Lycos", "query"), - "suche.lycos.de" => array("Lycos", "query"), - "search.lycos.de" => array("Lycos", "query"), - "sidesearch.lycos.com" => array("Lycos", "query"), - "www.multimania.lycos.fr" => array("Lycos", "query"), - "buscador.lycos.es" => array("Lycos", "query"), - - // Mail.ru - "go.mail.ru" => array("Mailru", "q"), - - // Mamma - "mamma.com" => array("Mamma", "query"), - "mamma75.mamma.com" => array("Mamma", "query"), - "www.mamma.com" => array("Mamma", "query"), - - // Meceoo - "www.meceoo.fr" => array("Meceoo", "kw"), - - // Mediaset - "servizi.mediaset.it" => array("Mediaset", "searchword"), - - // Metacrawler - "search.metacrawler.com" => array("Metacrawler", "general"), - - // Metager - "mserv.rrzn.uni-hannover.de" => array("Metager", "eingabe"), - "www.metager.de" => array("Metager", "eingabe"), - - // Metager2 - "www.metager2.de" => array("Metager2", "q"), - "metager2.de" => array("Metager2", "q"), - - // Meinestadt - "www.meinestadt.de" => array("Meinestadt.de", "words"), - - // Monstercrawler - "www.monstercrawler.com" => array("Monstercrawler", "qry"), - - // Mozbot - "www.mozbot.fr" => array("mozbot", "q"), - "www.mozbot.co.uk" => array("mozbot", "q"), - "www.mozbot.com" => array("mozbot", "q"), - - // MSN - "search.msn.com" => array("MSN", "q"), - "beta.search.msn.fr" => array("MSN", "q"), - "search.msn.fr" => array("MSN", "q"), - "search.msn.es" => array("MSN", "q"), - "search.msn.se" => array("MSN", "q"), - "search.latam.msn.com" => array("MSN", "q"), - "search.msn.nl" => array("MSN", "q"), - "leguide.fr.msn.com" => array("MSN", "s"), - "leguide.msn.fr" => array("MSN", "s"), - "search.msn.co.jp" => array("MSN", "q"), - "search.msn.no" => array("MSN", "q"), - "search.msn.at" => array("MSN", "q"), - "search.msn.com.hk" => array("MSN", "q"), - "search.t1msn.com.mx" => array("MSN", "q"), - "fr.ca.search.msn.com" => array("MSN", "q"), - "search.msn.be" => array("MSN", "q"), - "search.fr.msn.be" => array("MSN", "q"), - "search.msn.it" => array("MSN", "q"), - "sea.search.msn.it" => array("MSN", "q"), - "sea.search.msn.fr" => array("MSN", "q"), - "sea.search.msn.de" => array("MSN", "q"), - "sea.search.msn.com" => array("MSN", "q"), - "sea.search.fr.msn.be" => array("MSN", "q"), - "search.msn.com.tw" => array("MSN", "q"), - "search.msn.de" => array("MSN", "q"), - "search.msn.co.uk" => array("MSN", "q"), - "search.msn.co.za" => array("MSN", "q"), - "search.msn.ch" => array("MSN", "q"), - "search.msn.es" => array("MSN", "q"), - "search.msn.com.br" => array("MSN", "q"), - "search.ninemsn.com.au" => array("MSN", "q"), - "search.msn.dk" => array("MSN", "q"), - "search.arabia.msn.com" => array("MSN", "q"), - "search.prodigy.msn.com" => array("MSN", "q"), - - // El Mundo - "ariadna.elmundo.es" => array("El Mundo", "q"), - - // MyWebSearch - "kf.mysearch.myway.com" => array("MyWebSearch", "searchfor"), - "ms114.mysearch.com" => array("MyWebSearch", "searchfor"), - "ms146.mysearch.com" => array("MyWebSearch", "searchfor"), - "mysearch.myway.com" => array("MyWebSearch", "searchfor"), - "searchfr.myway.com" => array("MyWebSearch", "searchfor"), - "ki.mysearch.myway.com" => array("MyWebSearch", "searchfor"), - "search.mywebsearch.com" => array("MyWebSearch", "searchfor"), - "www.mywebsearch.com" => array("MyWebSearch", "searchfor"), - - // Najdi - "www.najdi.si" => array("Najdi.si", "q"), - - // Needtofind - "ko.search.need2find.com" => array("Needtofind", "searchfor"), - - // Netster - "www.netster.com" => array("Netster", "keywords"), - - // Netscape - "search-intl.netscape.com" => array("Netscape", "search"), - "www.netscape.fr" => array("Netscape", "q"), - "suche.netscape.de" => array("Netscape", "q"), - "search.netscape.com" => array("Netscape", "query"), - - // Nomade - "ie4.nomade.fr" => array("Nomade", "s"), - "rechercher.nomade.aliceadsl.fr"=> array("Nomade (AliceADSL)", "s"), - "rechercher.nomade.fr" => array("Nomade", "s"), - - // Northern Light - "www.northernlight.com" => array("Northern Light", "qr"), - - // Numéricable - "www.numericable.fr" => array("Numéricable", "query"), - - // Onet - "szukaj.onet.pl" => array("Onet.pl", "qt"), - - // Opera - "search.opera.com" => array("Opera", "search"), - - // Openfind - "wps.openfind.com.tw" => array("Openfind (Websearch)", "query"), - "bbs2.openfind.com.tw" => array("Openfind (BBS)", "query"), - "news.openfind.com.tw" => array("Openfind (News)", "query"), - - // Overture - "www.overture.com" => array("Overture", "Keywords"), - "www.fr.overture.com" => array("Overture", "Keywords"), - - // Paperball - "suche.paperball.de" => array("Paperball", "query"), - - // Picsearch - "www.picsearch.com" => array("Picsearch", "q"), - - // Plazoo - "www.plazoo.com" => array("Plazoo", "q"), - - // Postami - "www.postami.com" => array("Postami", "query"), - - // Quick searches - "data.quicksearches.net" => array("QuickSearches", "q"), - - // Qualigo - "www.qualigo.de" => array("Qualigo", "q"), - "www.qualigo.ch" => array("Qualigo", "q"), - "www.qualigo.at" => array("Qualigo", "q"), - "www.qualigo.nl" => array("Qualigo", "q"), - - // Rambler - "search.rambler.ru" => array("Rambler", "words"), - - // Reacteur.com - "www.reacteur.com" => array("Reacteur", "kw"), - - // Sapo - "pesquisa.sapo.pt" => array("Sapo","q"), - - // Search.com - "www.search.com" => array("Search.com", "q"), - - // Search.ch - "www.search.ch" => array("Search.ch", "q"), - - // Search a lot - "www.searchalot.com" => array("Searchalot", "query"), - - // Seek - "www.seek.fr" => array("Searchalot", "qry_str"), - - // Seekport - "www.seekport.de" => array("Seekport", "query"), - "www.seekport.co.uk" => array("Seekport", "query"), - "www.seekport.fr" => array("Seekport", "query"), - "www.seekport.at" => array("Seekport", "query"), - "www.seekport.es" => array("Seekport", "query"), - "www.seekport.it" => array("Seekport", "query"), - - // Seekport (blogs) - "blogs.seekport.de" => array("Seekport (Blogs)", "query"), - "blogs.seekport.co.uk" => array("Seekport (Blogs)", "query"), - "blogs.seekport.fr" => array("Seekport (Blogs)", "query"), - "blogs.seekport.at" => array("Seekport (Blogs)", "query"), - "blogs.seekport.es" => array("Seekport (Blogs)", "query"), - "blogs.seekport.it" => array("Seekport (Blogs)", "query"), - - // Seekport (news) - "news.seekport.de" => array("Seekport (News)", "query"), - "news.seekport.co.uk" => array("Seekport (News)", "query"), - "news.seekport.fr" => array("Seekport (News)", "query"), - "news.seekport.at" => array("Seekport (News)", "query"), - "news.seekport.es" => array("Seekport (News)", "query"), - "news.seekport.it" => array("Seekport (News)", "query"), - - // Searchscout - "www.searchscout.com" => array("Search Scout", "gt_keywords"), - - // Searchy - "www.searchy.co.uk" => array("Searchy", "search_term"), - - // Seznam - "search1.seznam.cz" => array("Seznam", "q"), - "search2.seznam.cz" => array("Seznam", "q"), - "search.seznam.cz" => array("Seznam", "q"), - - // Sharelook - "www.sharelook.fr" => array("Sharelook", "keyword"), - "www.sharelook.de" => array("Sharelook", "keyword"), - - // Skynet - "search.skynet.be" => array("Skynet", "keywords"), - - // Sphere - "www.sphere.com" => array("Sphere", "q"), - - // Startpagina - "startgoogle.startpagina.nl" => array("Startpagina (Google)", "q"), - - // Suchnase - "www.suchnase.de" => array("Suchnase", "qkw"), - - // Supereva - "search.supereva.com" => array("Supereva", "q"), - - // Sympatico - "search.sympatico.msn.ca" => array("Sympatico", "q"), - "search.sli.sympatico.ca" => array("Sympatico", "q"), - "search.fr.sympatico.msn.ca" => array("Sympatico", "q"), - "sea.search.fr.sympatico.msn.ca"=> array("Sympatico", "q"), - - // Suchmaschine.com - "www.suchmaschine.com" => array("Suchmaschine.com", "suchstr"), - - //Technorati - "www.technorati.com" => array("Technorati", " "), - - // Teoma - "www.teoma.com" => array("Teoma", "t"), - - // Tiscali - "rechercher.nomade.tiscali.fr" => array("Tiscali", "s"), - "search-dyn.tiscali.it" => array("Tiscali", "key"), - "www.tiscali.co.uk" => array("Tiscali", "query"), - "search-dyn.tiscali.de" => array("Tiscali", "key"), - "hledani.tiscali.cz" => array("Tiscali", "query", "windows-1250"), - - // T-Online - "suche.t-online.de" => array("T-Online", "q"), - - // Trouvez.com - "www.trouvez.com" => array("Trouvez.com", "query"), - - // Trusted-Search - - "www.trusted--search.com" => array("Trusted Search", "w"), - - // Vinden - "zoek.vinden.nl" => array("Vinden", "query"), - - // Vindex - "www.vindex.nl" => array("Vindex","search_for"), - - // Virgilio - "search.virgilio.it" => array("Virgilio", "qs"), - - // Voila - "search.voila.com" => array("Voila", "kw"), - "search.ke.voila.fr" => array("Voila", "rdata"), - "moteur.voila.fr" => array("Voila", "kw"), - "search.voila.fr" => array("Voila", "kw"), - "beta.voila.fr" => array("Voila", "kw"), - - // Volny - "web.volny.cz" => array("Volny", "search", "windows-1250"), - - // Wanadoo - "search.ke.wanadoo.fr" => array("Wanadoo", "kw"), - "busca.wanadoo.es" => array("Wanadoo", "buscar"), - - // Web.de - "suche.web.de" => array("Web.de (Websuche)", "su"), - "dir.web.de" => array("Web.de (Directory)", "su"), - - // Webtip - "www.webtip.de" => array("Webtip", "keyword"), - - // X-recherche - "www.x-recherche.com" => array("X-Recherche", "mots"), - - // Yahoo - "search.yahoo.com" => array("Yahoo!", "p"), - "ink.yahoo.com" => array("Yahoo!", "p"), - "ink.yahoo.fr" => array("Yahoo!", "p"), - "fr.ink.yahoo.com" => array("Yahoo!", "p"), - "search.yahoo.co.jp" => array("Yahoo!", "p"), - "search.yahoo.fr" => array("Yahoo!", "p"), - "ar.search.yahoo.com" => array("Yahoo!", "p"), - "br.search.yahoo.com" => array("Yahoo!", "p"), - "ch.search.yahoo.com" => array("Yahoo!", "p"), - "de.search.yahoo.com" => array("Yahoo!", "p"), - "ca.search.yahoo.com" => array("Yahoo!", "p"), - "cf.search.yahoo.com" => array("Yahoo!", "p"), - "fr.search.yahoo.com" => array("Yahoo!", "p"), - "espanol.search.yahoo.com" => array("Yahoo!", "p"), - "es.search.yahoo.com" => array("Yahoo!", "p"), - "id.search.yahoo.com" => array("Yahoo!", "p"), - "it.search.yahoo.com" => array("Yahoo!", "p"), - "kr.search.yahoo.com" => array("Yahoo!", "p"), - "mx.search.yahoo.com" => array("Yahoo!", "p"), - "nl.search.yahoo.com" => array("Yahoo!", "p"), - "uk.search.yahoo.com" => array("Yahoo!", "p"), - "cade.search.yahoo.com" => array("Yahoo!", "p"), - "tw.search.yahoo.com" => array("Yahoo!", "p"), - "www.yahoo.com.cn" => array("Yahoo!", "p"), - - "de.dir.yahoo.com" => array("Yahoo! Webverzeichnis", ""), - "cf.dir.yahoo.com" => array("Yahoo! Directory", ""), - "fr.dir.yahoo.com" => array("Yahoo! Directory", ""), - - // Yandex - "www.yandex.ru" => array("Yandex", "text"), - "yandex.ru" => array("Yandex", "text"), - "search.yaca.yandex.ru" => array("Yandex", "text"), - "ya.ru" => array("Yandex", "text"), - "www.ya.ru" => array("Yandex", "text"), - "images.yandex.ru" => array("Yandex Images","text"), - - //Yellowmap - - "www.yellowmap.de" => array("Yellowmap", " "), - "yellowmap.de" => array("Yellowmap", " "), - - // Wanadoo - "search.ke.wanadoo.fr" => array("Wanadoo", "kw"), - "busca.wanadoo.es" => array("Wanadoo", "buscar"), - - // Wedoo - "fr.wedoo.com" => array("Wedoo", "keyword"), - - // Web.nl - "www.web.nl" => array("Web.nl","query"), - - // Weborama - "www.weborama.fr" => array("weborama", "query"), - - // WebSearch - "is1.websearch.com" => array("WebSearch", "qkw"), - "www.websearch.com" => array("WebSearch", "qkw"), - "websearch.cs.com" => array("WebSearch", "query"), - - // Witch - "www.witch.de" => array("Witch", "search"), - - // WXS - "wxsl.nl" => array("Planet Internet","q"), - - // Zoek - "www3.zoek.nl" => array("Zoek","q"), - - // Zhongsou - "p.zhongsou.com" => array("Zhongsou","w"), - - // Zoeken - "www.zoeken.nl" => array("Zoeken","query"), - - // Zoohoo - "zoohoo.cz" => array("Zoohoo", "q", "windows-1250"), - "www.zoohoo.cz" => array("Zoohoo", "q", "windows-1250"), - - // Zoznam - "www.zoznam.sk" => array("Zoznam", "s"), - ); - - $GLOBALS['Piwik_SearchEngines_NameToUrl'] = array(); - foreach($GLOBALS['Piwik_SearchEngines'] as $url => $info) - { - if(!isset($GLOBALS['Piwik_SearchEngines_NameToUrl'][$info[0]])) - { - $GLOBALS['Piwik_SearchEngines_NameToUrl'][$info[0]] = $url; - } - } - -} - diff --git a/modules/DataTable.php b/modules/DataTable.php deleted file mode 100644 index f29e4bf9f1..0000000000 --- a/modules/DataTable.php +++ /dev/null @@ -1,1014 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_DataTable - */ - -require_once "DataTable/Renderer.php"; -require_once "DataTable/Renderer/Console.php"; -require_once "DataTable/Filter.php"; -require_once "DataTable/Row.php"; -require_once "DataTable/Manager.php"; - -/** - * - * ---- DataTable - * A DataTable is a data structure used to store complex tables of data. - * - * A DataTable is composed of multiple DataTable_Row. - * A DataTable can be applied one or several DataTable_Filter. - * A DataTable can be given to a DataTable_Renderer that would export the data under a given format (XML, HTML, etc.). - * - * A DataTable has the following features: - * - serializable to be stored in the DB - * - loadable from the serialized version - * - efficient way of loading data from an external source (from a PHP array structure) - * - very simple interface to get data from the table - * - * ---- DataTable_Row - * A DataTableRow in the table is defined by - * - multiple columns (a label, multiple values, ...) - * - optional metadata - * - optional - a sub DataTable associated to this row - * - * Simple row example: - * - columns = array( 'label' => 'Firefox', - * 'visitors' => 155, - * 'pages' => 214, - * 'bounce_rate' => 67) - * - metadata = array('logo' => '/img/browsers/FF.png') - * - no sub DataTable - * - * A more complex example would be a DataTable_Row that is associated to a sub DataTable. - * For example, for the row of the search engine Google, - * we want to get the list of keywords associated, with their statistics. - * - columns = array( 'label' => 'Google', - * 'visits' => 1550, - * 'visits_length' => 514214, - * 'returning_visits' => 77) - * - metadata = array( 'logo' => '/img/search/google.png', - * 'url' => 'http://google.com') - * - DataTable = DataTable containing several DataTable_Row containing the keywords information for this search engine - * Example of one DataTable_Row - * - the keyword columns specific to this search engine = - * array( 'label' => 'Piwik', // the keyword - * 'visitors' => 155, // Piwik has been searched on Google by 155 visitors - * 'pages' => 214 // Visitors coming from Google with the kwd Piwik have seen 214 pages - * ) - * - the keyword metadata = array() // nothing here, but we could imagining storing the URL of the search in Google for example - * - no subTable - * - * - * ---- DataTable_Filter - * A DataTable_Filter is a applied to a DataTable and so - * can filter information in the multiple DataTable_Row. - * - * For example a DataTable_Filter can: - * - remove rows from the table, - * for example the rows' labels that do not match a given searched pattern - * for example the rows' values that are less than a given percentage (low population) - * - return a subset of the DataTable - * for example a function that apply a limit: $offset, $limit - * - add / remove columns - * for example adding a column that gives the percentage of a given value - * - add some metadata - * for example the 'logo' path if the filter detects the logo - * - edit the value, the label - * - change the rows order - * for example if we want to sort by Label alphabetical order, or by any column value - * - * When several DataTable_Filter are to be applied to a DataTable they are applied sequentially. - * A DataTable_Filter is assigned a priority. - * For example, filters that - * - sort rows should be applied with the highest priority - * - remove rows should be applied with a high priority as they prune the data and improve performance. - * - * ---- Code example - * - * $table = new DataTable; - * $table->loadFromArray( array(...) ); - * - * # sort the table by visits asc - * $filter = new DataTable_Filter_Sort( $table, 'visits', 'asc'); - * $tableFiltered = $filter->getTableFiltered(); - * - * # add a filter to select only the website with a label matching '*.com' (regular expression) - * $filter = new DataTable_Filter_Pattern( $table, 'label', '*(.com)'); - * $tableFiltered = $filter->getTableFiltered(); - * - * # keep the 20 elements from offset 15 - * $filter = new DataTable_Filter_Limit( $tableFiltered, 15, 20); - * $tableFiltered = $filter->getTableFiltered(); - * - * # add a column computing the percentage of visits - * # params = table, column containing the value, new column name to add, number of total visits to use to compute the % - * $filter = new DataTable_Filter_AddColumnPercentage( $tableFiltered, 'visits', 'visits_percentage', 2042); - * $tableFiltered = $filter->getTableFiltered(); - * - * # we get the table as XML - * $xmlOutput = new DataTable_Exporter_Xml( $table ); - * $xmlOutput->setHeader( ... ); - * $xmlOutput->setColumnsToExport( array('visits', 'visits_percent', 'label') ); - * $XMLstring = $xmlOutput->getOutput(); - * - * - * ---- Other (ideas) - * We can also imagine building a DataTable_Compare which would take N DataTable that have the same - * structure and would compare them, by computing the percentages of differences, etc. - * - * For example - * DataTable1 = [ keyword1, 1550 visits] - * [ keyword2, 154 visits ] - * DataTable2 = [ keyword1, 1004 visits ] - * [ keyword3, 659 visits ] - * DataTable_Compare = result of comparison of table1 with table2 - * [ keyword1, +154% ] - * [ keyword2, +1000% ] - * [ keyword3, -430% ] - * - * @see Piwik_DataTable_Row A Piwik_DataTable is composed of Piwik_DataTable_Row - * - * @package Piwik - * @subpackage Piwik_DataTable - * - */ - -class Piwik_DataTable -{ - /** - * Array of Piwik_DataTable_Row - * - * @var array - */ - protected $rows = array(); - - /** - * Id assigned to the DataTable, used to lookup the table using the DataTable_Manager - * - * @var int - */ - protected $currentId; - - /** - * Current depth level of this data table - * 0 is the parent data table - * - * @var int - */ - protected $depthLevel = 0; - - /** - * This flag is set to false once we modify the table in a way that outdates the index - * - * @var bool - */ - protected $indexNotUpToDate = false; - - /** - * List of Piwik_DataTable_Filter queued to this table - * - * @var array - */ - protected $queuedFilters = array(); - - /** - * We keep track of the number of rows before applying the LIMIT filter that deletes some rows - * - * @var int - */ - protected $rowsCountBeforeLimitFilter = 0; - - /** - * Defaults to false for performance reasons (most of the time we don't need recursive sorting so we save a looping over the dataTable) - * - * @var bool - */ - protected $enableRecursiveSort = false; - - /* - * @var Piwik_DataTable_Row - */ - protected $summaryRow = null; - - const ID_SUMMARY_ROW = -1; - const LABEL_SUMMARY_ROW = -1; - - /** - * Maximum nesting level - * - * @var int - */ - const MAXIMUM_DEPTH_LEVEL_ALLOWED = 20; - - /** - * Builds the DataTable, registers itself to the manager - * - */ - public function __construct() - { - $this->currentId = Piwik_DataTable_Manager::getInstance()->addTable($this); - } - - /** - * Sort the dataTable rows using the php callback function - * - * @param string $functionCallback - */ - public function sort( $functionCallback ) - { - $this->indexNotUpToDate = true; - usort( $this->rows, $functionCallback ); - - if($this->enableRecursiveSort === true) - { - foreach($this->getRows() as $row) - { - if(($idSubtable = $row->getIdSubDataTable()) !== null) - { - $table = Piwik_DataTable_Manager::getInstance()->getTable($idSubtable); - $table->enableRecursiveSort(); - $table->sort($functionCallback); - } - } - } - } - - /** - * Enables the recursive sort. Means that when using $table->sort() - * it will also sort all subtables using the same callback - * - * @return void - */ - public function enableRecursiveSort() - { - $this->enableRecursiveSort = true; - } - - /** - * Returns the number of rows before we applied the limit filter - * - * @return int - */ - public function getRowsCountBeforeLimitFilter() - { - $toReturn = $this->rowsCountBeforeLimitFilter; - if($toReturn == 0) - { - return $this->getRowsCount(); - } - return $toReturn; - } - - /** - * Saves the current number of rows - * - * @return void - * - */ - function setRowsCountBeforeLimitFilter() - { - $this->rowsCountBeforeLimitFilter = $this->getRowsCount(); - } - - /** - * Queue a DataTable_Filter that will be applied at the end of the process - * (just before sending the datatable back to the browser (or API, etc.) - * - * @param string $className The class name of the filter, eg. Piwik_DataTable_Filter_Limit - * @param array $parameters The parameters to give to the filter, eg. array( $offset, $limit) for the filter Piwik_DataTable_Filter_Limit - */ - public function queueFilter( $className, $parameters = array() ) - { - if(!is_array($parameters)) - { - $parameters = array($parameters); - } - $this->queuedFilters[] = array('className' => $className, 'parameters' => $parameters); - } - - /** - * Apply all filters that were previously queued to this table - * @see queueFilter() - * @return void - */ - public function applyQueuedFilters() - { - foreach($this->queuedFilters as $filter) - { - if($filter['className'] == 'Piwik_DataTable_Filter_Limit') - { - $this->setRowsCountBeforeLimitFilter(); - } - - $reflectionObj = new ReflectionClass($filter['className']); - - // the first parameter of a filter is the DataTable - // we add the current datatable as the parameter - $filter['parameters'] = array_merge(array($this), $filter['parameters']); - - $filter = $reflectionObj->newInstanceArgs($filter['parameters']); - } - $this->queuedFilters = array(); - } - - /** - * Adds a new DataTable to this DataTable - * Go through all the rows of the new DataTable and applies the algorithm: - * - if a row in $table doesnt exist in $this we add the new row to $this - * - if a row exists in both $table and $this we sum the columns values into $this - * - if a row in $this doesnt exist in $table we keep the row of $this without modification - * - * A common row to 2 DataTable is defined by the same label - * - * @example @see tests/modules/DataTable.test.php - */ - public function addDataTable( Piwik_DataTable $tableToSum ) - { - foreach($tableToSum->getRows() as $row) - { - $labelToLookFor = $row->getColumn('label'); - $rowFound = $this->getRowFromLabel( $labelToLookFor ); - if($rowFound === false) - { - if( $labelToLookFor === self::LABEL_SUMMARY_ROW ) - { - $this->addSummaryRow($row ); - } - else - { - $this->addRow( $row ); - } - } - else - { - $rowFound->sumRow( $row ); - - // if the row to add has a subtable whereas the current row doesn't - // we simply add it (cloning the subtable) - // if the row has the subtable already - // then we have to recursively sum the subtables - if(($idSubTable = $row->getIdSubDataTable()) !== null) - { - $rowFound->sumSubtable( Piwik_DataTable_Manager::getInstance()->getTable($idSubTable) ); - } - } - } - } - - /** - * Returns the Piwik_DataTable_Row that has a column 'label' with the value $label - * - * @param string $label Value of the column 'label' of the row to return - * @return Piwik_DataTable_Row|false The row if found, false otherwise - */ - public function getRowFromLabel( $label ) - { - if($this->indexNotUpToDate) - { - $this->rebuildIndex(); - } - - if($label === self::LABEL_SUMMARY_ROW - && !is_null($this->summaryRow)) - { - return $this->summaryRow; - } - - $label = (string)$label; - if(!isset($this->rowsIndexByLabel[$label])) - { - return false; - } - return $this->rows[$this->rowsIndexByLabel[$label]]; - } - - /** - * Rebuilds the index used to lookup a row by label - * - * @return void - */ - private function rebuildIndex() - { - foreach($this->rows as $id => $row) - { - $label = $row->getColumn('label'); - - if($label !== false) - { - $this->rowsIndexByLabel[$label] = $id; - } - } - $this->indexNotUpToDate = false; - } - - /** - * Returns the ith row in the array - * - * @param int $id - * @return Piwik_DataTable_Row or false if not found - */ - public function getRowFromId($id) - { - if(!isset($this->rows[$id])) - { - if($id == self::ID_SUMMARY_ROW - && !is_null($this->summaryRow)) - { - return $this->summaryRow; - } - return false; - } - return $this->rows[$id]; - } - - /** - * Shortcut function used for performance reasons - * - * @param Piwik_DataTable_Row $row to add at the end of the array - */ - public function addRow( Piwik_DataTable_Row $row ) - { - $this->rows[] = $row; - $this->indexNotUpToDate = true; - } - - /** - * Sets the summary row (a dataTable can have only one summary row) - * - * @param Piwik_DataTable_Row $row - */ - public function addSummaryRow( Piwik_DataTable_Row $row ) - { - $this->summaryRow = $row; - } - - /** - * Returns the dataTable ID - * - * @return int - */ - public function getId() - { - return $this->currentId; - } - - /** - * Adds a new row from a PHP array data structure - * - * @param array $row, eg. array(Piwik_DataTable_Row::COLUMNS => array( 'visits' => 13, 'test' => 'toto'),) - */ - public function addRowFromArray( $row ) - { - $this->loadFromArray(array($row)); - } - - /** - * Adds a new row a PHP array data structure - * - * @param array $row, eg. array('name' => 'google analytics', 'license' => 'commercial') - */ - public function addRowFromSimpleArray( $row ) - { - $this->loadFromSimpleArray(array($row)); - } - - /** - * Returns the array of Piwik_DataTable_Row - * - * @return array of Piwik_DataTable_Row - */ - public function getRows() - { - if(is_null($this->summaryRow)) - { - return $this->rows; - } - else - { - return $this->rows + array(self::ID_SUMMARY_ROW => $this->summaryRow); - } - } - - /** - * Returns the number of rows in the table - * - * @return int - */ - public function getRowsCount() - { - $count = count($this->rows); - if(is_null($this->summaryRow)) - { - return $count; - } - else - { - return $count + 1; - } - } - - /** - * Returns the first row of the DataTable - * - * @return Piwik_DataTable_Row - */ - public function getFirstRow() - { - if(count($this->rows) == 0) - { - if(!is_null($this->summaryRow)) - { - return $this->summaryRow; - } - return false; - } - $row = array_slice($this->rows, 0, 1); - return $row[0]; - } - - /** - * Returns the last row of the DataTable - * - * @return Piwik_DataTable_Row - */ - public function getLastRow() - { - if(!is_null($this->summaryRow)) - { - return $this->summaryRow; - } - - if(count($this->rows) == 0) - { - return false; - } - $row = array_slice($this->rows, -1); - return $row[0]; - } - - /** - * Returns the sum of the number of rows of all the subtables - * + the number of rows in the parent table - * - * @return int - */ - public function getRowsCountRecursive() - { - $totalCount = 0; - foreach($this->rows as $row) - { - if(($idSubTable = $row->getIdSubDataTable()) !== null) - { - $subTable = Piwik_DataTable_Manager::getInstance()->getTable($idSubTable); - $count = $subTable->getRowsCountRecursive(); - $totalCount += $count; - } - } - - $totalCount += $this->getRowsCount(); - return $totalCount; - } - - /** - * Delete a given column $name in all the rows - * - * @param string $name - */ - public function deleteColumn( $name ) - { - foreach($this->getRows() as $row) - { - $row->deleteColumn($name); - } - if(!is_null($this->summaryRow)) - { - $this->summaryRow->deleteColumn($name); - } - } - - /** - * Deletes the ith row - * - * @param int $key - * @throws Exception if the row $id cannot be found - */ - public function deleteRow( $id ) - { - if($id === self::ID_SUMMARY_ROW) - { - $this->summaryRow = null; - return; - } - if(!isset($this->rows[$id])) - { - throw new Exception("Trying to delete unknown row with idkey = $id"); - } - unset($this->rows[$id]); - } - - /** - * Deletes all row from offset, offset + limit. - * If limit is null then limit = $table->getRowsCount() - * - * @param int $offset - * @param int $limit - */ - public function deleteRowsOffset( $offset, $limit = null ) - { - if($limit === 0) - { - return; - } - - $count = $this->getRowsCount(); - if($offset >= $count) - { - return; - } - - // if we delete until the end, we delete the summary row as well - if( is_null($limit) - || $limit >= $count ) - { - $this->summaryRow = null; - } - - if(is_null($limit)) - { - array_splice($this->rows, $offset); - } - else - { - array_splice($this->rows, $offset, $limit); - } - } - - /** - * Deletes the rows from the list of rows ID - * - * @param array $aKeys ID of the rows to delete - * @throws Exception if any of the row to delete couldn't be found - */ - public function deleteRows( array $aKeys ) - { - foreach($aKeys as $key) - { - $this->deleteRow($key); - } - } - - /** - * Returns a simple output of the DataTable for easy visualization - * Example: echo $datatable; - * - * @return string - */ - public function __toString() - { - $renderer = new Piwik_DataTable_Renderer_Console($this); - return (string)$renderer; - } - - /** - * Returns true if both DataTable are exactly the same. - * Used in unit tests. - * - * @param Piwik_DataTable $table1 - * @param Piwik_DataTable $table2 - * @return bool - */ - static public function isEqual(Piwik_DataTable $table1, Piwik_DataTable $table2) - { - $rows1 = $table1->getRows(); - $rows2 = $table2->getRows(); - - $table1->rebuildIndex(); - $table2->rebuildIndex(); - - $countrows1 = $table1->getRowsCount(); - $countrows2 = $table2->getRowsCount(); - - if($countrows1 != $countrows2) - { - return false; - } - - foreach($rows1 as $row1) - { - $row2 = $table2->getRowFromLabel($row1->getColumn('label')); - if($row2 === false) - { - return false; - } - if( !Piwik_DataTable_Row::isEqual($row1,$row2) ) - { - return false; - } - } - - return true; - } - - /** - * The serialization returns a one dimension array containing all the - * serialized DataTable contained in this DataTable. - * We save DataTable in serialized format in the Database. - * Each row of this returned PHP array will be a row in the DB table. - * - * The keys of the array are very important as they are used to define the DataTable - * - * IMPORTANT: The main table (level 0, parent of all tables) will always be indexed by 0 - * even it was created after some other tables. - * It also means that all the parent tables (level 0) will be indexed with 0 in their respective - * serialized arrays. You should never lookup a parent table using the getTable( $id = 0) as it - * won't work. - * - * @throws Exception if an infinite recursion is found (a table row's has a subtable that is one of its parent table) - * @param int If not null, defines the number of rows maximum of the serialized dataTable - * If $addSummaryRowAfterNRows is less than the size of the table, a SummaryRow will be added at the end of the table, that - * is the sum of the values of all the rows after the Nth row. All the rows after the Nth row will be deleted. - * - * @return array Serialized arrays - * array( // Datatable level0 - * 0 => 'eghuighahgaueytae78yaet7yaetae', - * - * // first Datatable level1 - * 1 => 'gaegae gh gwrh guiwh uigwhuige', - * - * //second Datatable level1 - * 2 => 'gqegJHUIGHEQjkgneqjgnqeugUGEQHGUHQE', - * - * //first Datatable level3 (child of second Datatable level1 for example) - * 3 => 'eghuighahgaueytae78yaet7yaetaeGRQWUBGUIQGH&QE', - * ); - * - */ - public function getSerialized( $maximumRowsInDataTable = null, $maximumRowsInSubDataTable = null ) - { - static $depth = 0; - - if($depth > self::MAXIMUM_DEPTH_LEVEL_ALLOWED) - { - throw new Exception("Maximum recursion level of ".self::MAXIMUM_DEPTH_LEVEL_ALLOWED. " reached. You have probably set a DataTable_Row with an associated DataTable which belongs already to its parent hierarchy."); - } - - if( !is_null($maximumRowsInDataTable) ) - { - $filter = new Piwik_DataTable_Filter_AddSummaryRow($this, $maximumRowsInDataTable - 1); - } - - // For each row, get the serialized row - // If it is associated to a sub table, get the serialized table recursively ; - // but returns all serialized tables and subtable in an array of 1 dimension! - $aSerializedDataTable = array(); - foreach($this->rows as $row) - { - if(($idSubTable = $row->getIdSubDataTable()) !== null) - { - $subTable = Piwik_DataTable_Manager::getInstance()->getTable($idSubTable); - $depth++; - $aSerializedDataTable = $aSerializedDataTable + $subTable->getSerialized( $maximumRowsInSubDataTable, $maximumRowsInSubDataTable ); - $depth--; - } - } - // we load the current Id of the DataTable - $forcedId = $this->getId(); - - // if the datatable is the parent we force the Id at 0 (this is part of the specification) - if($depth == 0) - { - $forcedId = 0; - } - - // we then serialize the rows and store them in the serialized dataTable - $aSerializedDataTable[$forcedId] = serialize($this->rows + array( self::ID_SUMMARY_ROW => $this->summaryRow)); - - return $aSerializedDataTable; - } - - /** - * Load a serialized string of a datatable. - * - * Does not load recursively all the sub DataTable. - * They will be loaded only when requesting them specifically. - * - * The function creates all the necessary DataTable_Row - * - * @param string Serialized string of a datatable - * @return void - */ - public function loadFromSerialized( $stringSerialized ) - { - $serialized = unserialize($stringSerialized); - if($serialized === false) - { - throw new Exception("The unserialization has failed!"); - } - $this->loadFromArray($serialized); - } - - /** - * Loads the DataTable from a PHP array data structure - * - * @param array Array with the following structure - * array( - * // row1 - * array( - * Piwik_DataTable_Row::COLUMNS => array( col1_name => value1, col2_name => value2, ...), - * Piwik_DataTable_Row::METADATA => array( metadata1_name => value1, ...), // see Piwik_DataTable_Row - * - * ), - * - * // row2 - * array( ... ), - * - * ) - * @return void - */ - public function loadFromArray( $array ) - { - foreach($array as $id => $row) - { - if(is_array($row)) - { - $row = new Piwik_DataTable_Row($row); - } - if($id == self::ID_SUMMARY_ROW) - { - $this->summaryRow = $row; - } - else - { - $this->addRow($row); - } - } - } - - /** - * Loads the data from a simple php array. - * Basically maps a simple multidimensional php array to a DataTable. - * Not recursive (if a row contains a php array itself, it won't be loaded) - * - * @param array Array with the simple structure: - * array( - * array( col1_name => valueA, col2_name => valueC, ...), - * array( col1_name => valueB, col2_name => valueD, ...), - * ) - */ - public function loadFromSimpleArray( $array ) - { - if(count($array) === 0) - { - return; - } - - // we define an exception we may throw if at one point we notice that we cannot handle the data structure - $e = new Exception(" Data structure returned is not convertible in the requested format.". - " Try to call this method with the parameters '&format=original&serialize=1'". - "; you will get the original php data structure serialized.". - " The data structure looks like this: \n \$data = " . var_export($array, true) . "; "); - - - // first pass to see if the array has the structure - // array(col1_name => val1, col2_name => val2, etc.) - // with val* that are never arrays (only strings/numbers/bool/etc.) - // if we detect such a "simple" data structure we convert it to a row with the correct columns' names - $thisIsNotThatSimple = false; - - foreach($array as $columnName => $columnValue ) - { - if(is_array($columnValue) || is_object($columnValue)) - { - $thisIsNotThatSimple = true; - break; - } - } - if($thisIsNotThatSimple === false) - { - // case when the array is indexed by the default numeric index - if( array_keys($array) == array_keys(array_fill(0, count($array), true)) ) - { - foreach($array as $row) - { - $this->addRow( new Piwik_DataTable_Row( array( Piwik_DataTable_Row::COLUMNS => array($row) ) ) ); - } - } - else - { - $this->addRow( new Piwik_DataTable_Row( array( Piwik_DataTable_Row::COLUMNS => $array ) ) ); - } - // we have converted our simple array to one single row - // => we exit the method as the job is now finished - return; - } - - - foreach($array as $key => $row) - { - // stuff that looks like a line - if(is_array($row)) - { - /** - * We make sure we can convert this PHP array without losing information. - * We are able to convert only simple php array (no strings keys, no sub arrays, etc.) - * - */ - - // if the key is a string it means that some information was contained in this key. - // it cannot be lost during the conversion. Because we are not able to handle properly - // this key, we throw an explicit exception. - if(is_string($key)) - { - throw $e; - } - // if any of the sub elements of row is an array we cannot handle this data structure... - foreach($row as $subRow) - { - if(is_array($subRow)) - { - throw $e; - } - } - $row = new Piwik_DataTable_Row( array( Piwik_DataTable_Row::COLUMNS => $row ) ); - } - // other (string, numbers...) => we build a line from this value - else - { - $row = new Piwik_DataTable_Row( array( Piwik_DataTable_Row::COLUMNS => array($key => $row)) ); - } - $this->addRow($row); - } - } - - /** - * Rewrites the input $array - * array ( - * LABEL => array(col1 => X, col2 => Y), - * LABEL2 => array(col1 => X, col2 => Y), - * ) - * - * to the structure - * array ( - * array( Piwik_DataTable_Row::COLUMNS => array('label' => LABEL, col1 => X, col2 => Y)), - * array( Piwik_DataTable_Row::COLUMNS => array('label' => LABEL2, col1 => X, col2 => Y)), - * ) - * - * The optional parameter $subtablePerLabel is an array of subTable associated to the rows of the $array - * For example if $subtablePerLabel is given - * array( - * LABEL => #Piwik_DataTable_ForLABEL, - * LABEL2 => #Piwik_DataTable_ForLABEL2, - * ) - * - * the $array would become - * array ( - * array( Piwik_DataTable_Row::COLUMNS => array('label' => LABEL, col1 => X, col2 => Y), - * Piwik_DataTable_Row::DATATABLE_ASSOCIATED => #ID DataTable For LABEL - * ), - * array( Piwik_DataTable_Row::COLUMNS => array('label' => LABEL2, col1 => X, col2 => Y) - * Piwik_DataTable_Row::DATATABLE_ASSOCIATED => #ID2 DataTable For LABEL2 - * ), - * ) - * - * @param array $array See method description - * @param array|null $subtablePerLabel see method description - * - * @return void - */ - public function loadFromArrayLabelIsKey( $array, $subtablePerLabel = null) - { - $cleanRow = array(); - foreach($array as $label => $row) - { - // we make sure that the label column is first in the list! - // important for the UI javascript mainly... - // array_merge doesn't work here as it reindex the numeric value - // see the test testMergeArray in PHP_Related.test.php - $cleanRow[Piwik_DataTable_Row::COLUMNS] = array('label' => $label) + $row; - if(!is_null($subtablePerLabel) - // some rows of this table don't have subtables - // (for examplecase of the campaign without keywords ) - && isset($subtablePerLabel[$label]) - ) - { - $cleanRow[Piwik_DataTable_Row::DATATABLE_ASSOCIATED] = $subtablePerLabel[$label]; - } - $this->addRow( new Piwik_DataTable_Row($cleanRow) ); - } - } - - /** - * At destruction we try to free memory - * But php doesn't give us much control on this - */ - public function __destruct() - { - unset($this->rows); - } - -} diff --git a/modules/DataTable/Array.php b/modules/DataTable/Array.php deleted file mode 100644 index c4624d0840..0000000000 --- a/modules/DataTable/Array.php +++ /dev/null @@ -1,152 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id: Simple.php 168 2008-01-14 05:26:43Z matt $ - * - * @package Piwik_DataTable - */ - -/** - * The DataTable_Array is a way to store an array of dataTable. - * The Piwik_DataTable_Array implements some of the features of the Piwik_DataTable such as queueFilter, getRowsCount. - * - * @package Piwik_DataTable - */ -class Piwik_DataTable_Array -{ - /** - * Used to store additional information about the DataTable Array. - * For example if the Array is used to store multiple DataTable of UserCountry, - * we can add the metadata of the 'idSite' they refer to, so we can access it later if necessary. - * - * @var array of mixed - */ - public $metadata = array(); - - /** - * Array containing the DataTable withing this Piwik_DataTable_Array - * - * @var array of Piwik_DataTable - */ - protected $array = array(); - - /** - * This is the label used to index the tables. - * For example if the tables are indexed using the timestamp of each period - * eg. $this->array[1045886960] = new Piwik_DataTable; - * the keyName would be 'timestamp'. - * - * This label is used in the Renderer (it becomes a column name or the XML description tag) - * - * @var string - */ - protected $keyName = 'defaultKeyName'; - - /** - * Returns the keyName string @see self::$keyName - * - * @return string - */ - public function getKeyName() - { - return $this->keyName; - } - - /** - * Set the keyName @see self::$keyName - * - * @param string $name - */ - public function setKeyName($name) - { - $this->keyName = $name; - } - - /** - * Returns the number of DataTable in this DataTable_Array - * - * @return int - */ - public function getRowsCount() - { - return count($this->array); - } - - /** - * Queue a filter to the DataTable_Array will queue this filter to every DataTable of the DataTable_Array. - * - * @param string $className Filter name, eg. Piwik_DataTable_Filter_Limit - * @param array $parameters Filter parameters, eg. array( 50, 10 ) - * - * @return void - */ - public function queueFilter( $className, $parameters = array() ) - { - foreach($this->array as $table) - { - $table->queueFilter($className, $parameters); - } - } - - /** - * Apply the filters previously queued to each of the DataTable of this DataTable_Array. - * - * @return void - */ - public function applyQueuedFilters() - { - foreach($this->array as $table) - { - $table->applyQueuedFilters(); - } - } - - /** - * Returns the array of DataTable - * - * @return array of Piwik_DataTable - */ - public function getArray() - { - return $this->array; - } - - /** - * Adds a new DataTable to the DataTable_Array - * - * @param Piwik_DataTable $table - * @param string $label Label used to index this table in the array - */ - public function addTable( $table, $label ) - { - $this->array[$label] = $table; - } - - /** - * Returns a string output of this DataTable_Array (applying the default renderer to every DataTable - * of this DataTable_Array). - * - * @return string - */ - public function __toString() - { - $renderer = new Piwik_DataTable_Renderer_Console($this); - return (string)$renderer; - } - - /** - * @see Piwik_DataTable::enableRecursiveSort() - */ - public function enableRecursiveSort() - { - foreach($this->array as $table) - { - $table->enableRecursiveSort(); - } - } -} - - diff --git a/modules/DataTable/Filter.php b/modules/DataTable/Filter.php deleted file mode 100644 index a017d57e77..0000000000 --- a/modules/DataTable/Filter.php +++ /dev/null @@ -1,58 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_DataTable - */ - -/** - * A filter is applied instantly to a given DataTable and can - * - remove rows - * - change columns values (lowercase the strings, truncate, etc.) - * - add/remove columns or metadata (compute percentage values, add an 'icon' metadata based on the label, etc.) - * - add/remove/edit sub DataTable associated to some rows - * - whatever you can imagine - * - * The concept is very simple: the filter is given the DataTable - * and can do whatever is necessary on the data (in the filter() method). - * - * @package Piwik_DataTable - * @subpackage Piwik_DataTable_Filter - */ -abstract class Piwik_DataTable_Filter -{ - /* - * @var Piwik_DataTable - */ - protected $table; - - public function __construct($table) - { - if(!($table instanceof Piwik_DataTable)) - { - throw new Exception("The filter accepts only a Piwik_DataTable object."); - } - $this->table = $table; - } - - abstract protected function filter(); -} - -require_once "DataTable/Filter/ColumnCallbackDeleteRow.php"; -require_once "DataTable/Filter/ColumnCallbackAddMetadata.php"; -require_once "DataTable/Filter/ColumnCallbackReplace.php"; -require_once "DataTable/Filter/MetadataCallbackAddMetadata.php"; -require_once "DataTable/Filter/AddConstantMetadata.php"; -require_once "DataTable/Filter/Null.php"; -require_once "DataTable/Filter/ExcludeLowPopulation.php"; -require_once "DataTable/Filter/Limit.php"; -require_once "DataTable/Filter/Pattern.php"; -require_once "DataTable/Filter/PatternRecursive.php"; -require_once "DataTable/Filter/ReplaceColumnNames.php"; -require_once "DataTable/Filter/Sort.php"; -require_once "DataTable/Filter/AddSummaryRow.php"; -require_once "DataTable/Filter/ReplaceSummaryRowLabel.php"; diff --git a/modules/DataTable/Filter/AddConstantMetadata.php b/modules/DataTable/Filter/AddConstantMetadata.php deleted file mode 100644 index 33c573120b..0000000000 --- a/modules/DataTable/Filter/AddConstantMetadata.php +++ /dev/null @@ -1,43 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_DataTable - */ - -/** - * Add a new metadata column to the table. - * - * This is used to add a column containing the logo width and height of the countries flag icons. - * This value is fixed for all icons so we simply add the same value for all rows. - * - * @package Piwik_DataTable - * @subpackage Piwik_DataTable_Filter - */ -class Piwik_DataTable_Filter_AddConstantMetadata extends Piwik_DataTable_Filter -{ - private $metadataToRead; - private $functionToApply; - private $metadataToAdd; - - public function __construct( $table, $metadataName, $metadataValue ) - { - parent::__construct($table); - $this->name = $metadataName; - $this->value = $metadataValue; - $this->filter(); - } - - protected function filter() - { - foreach($this->table->getRows() as $row) - { - $row->addMetadata($this->name, $this->value); - } - } -} - diff --git a/modules/DataTable/Filter/AddSummaryRow.php b/modules/DataTable/Filter/AddSummaryRow.php deleted file mode 100644 index b8d956dd43..0000000000 --- a/modules/DataTable/Filter/AddSummaryRow.php +++ /dev/null @@ -1,67 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id: Limit.php 168 2008-01-14 05:26:43Z matt $ - * - * @package Piwik_DataTable - */ - -/** - * Add a new row to the table containing a summary - * of the rows from StartRowToSummarize to EndRowToSummarize. - * It then deletes the rows from StartRowToSummarize to EndRowToSummarize. - * The new row created has a label = 'other' - * - * This filter is useful to build a more compact view of a table, - * keeping the first records unchanged. - * - * For example we use this for the pie chart, to build the last pie part - * which is the sum of all the remaining data after the top 5 data. - * This row is assigned a label of 'Others'. - * - * @package Piwik_DataTable - * @subpackage Piwik_DataTable_Filter - */ -class Piwik_DataTable_Filter_AddSummaryRow extends Piwik_DataTable_Filter -{ - public function __construct( $table, $startRowToSummarize, $labelSummaryRow = Piwik_DataTable::LABEL_SUMMARY_ROW, $columnToSortByBeforeTruncating = Piwik_Archive::INDEX_NB_VISITS ) - { - parent::__construct($table); - $this->startRowToSummarize = $startRowToSummarize; - $this->labelSummaryRow = $labelSummaryRow; - $this->columnToSortByBeforeTruncating = $columnToSortByBeforeTruncating; - - if($table->getRowsCount() > $startRowToSummarize + 1) - { - $this->filter(); - } - } - - protected function filter() - { - $filter = new Piwik_DataTable_Filter_Sort($this->table, $this->columnToSortByBeforeTruncating, 'desc'); - - $rows = $this->table->getRows(); - $count = $this->table->getRowsCount(); - $newRow = new Piwik_DataTable_Row(); - for($i = $this->startRowToSummarize; $i < $count; $i++) - { - if(!isset($rows[$i])) - { - // case when the last row is a summary row, it is not indexed by $cout but by Piwik_DataTable::ID_SUMMARY_ROW - $summaryRow = $this->table->getRowFromId(Piwik_DataTable::ID_SUMMARY_ROW); - $newRow->sumRow($summaryRow); - } - else - { - $newRow->sumRow($rows[$i]); - } - } - $newRow->addColumn('label', $this->labelSummaryRow); - $filter = new Piwik_DataTable_Filter_Limit($this->table, 0, $this->startRowToSummarize); - $this->table->addSummaryRow($newRow); - } -} diff --git a/modules/DataTable/Filter/ColumnCallbackAddMetadata.php b/modules/DataTable/Filter/ColumnCallbackAddMetadata.php deleted file mode 100644 index d3f81d2061..0000000000 --- a/modules/DataTable/Filter/ColumnCallbackAddMetadata.php +++ /dev/null @@ -1,49 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_DataTable - */ - - -/** - * Add a new 'metadata' column to the table based on the value resulting - * from a callback function with the parameter being another column's value - * - * For example from the "label" column we can to create an "icon" 'metadata' column - * with the icon URI built from the label (LINUX => UserSettings/icons/linux.png) - * - * @package Piwik_DataTable - * @subpackage Piwik_DataTable_Filter - */ - -class Piwik_DataTable_Filter_ColumnCallbackAddMetadata extends Piwik_DataTable_Filter -{ - private $columnToRead; - private $functionToApply; - private $metadataToAdd; - - public function __construct( $table, $columnToRead, $metadataToAdd, $functionToApply ) - { - parent::__construct($table); - $this->functionToApply = $functionToApply; - $this->columnToRead = $columnToRead; - $this->metadataToAdd = $metadataToAdd; - $this->filter(); - } - - protected function filter() - { - foreach($this->table->getRows() as $key => $row) - { - $oldValue = $row->getColumn($this->columnToRead); - $newValue = call_user_func( $this->functionToApply, $oldValue); - $row->addMetadata($this->metadataToAdd, $newValue); - } - } -} - diff --git a/modules/DataTable/Filter/ColumnCallbackDeleteRow.php b/modules/DataTable/Filter/ColumnCallbackDeleteRow.php deleted file mode 100644 index 8367d67b44..0000000000 --- a/modules/DataTable/Filter/ColumnCallbackDeleteRow.php +++ /dev/null @@ -1,44 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_DataTable - */ - -/** - * Delete all rows for which a given function returns false for a given column. - * - * @package Piwik_DataTable - * @subpackage Piwik_DataTable_Filter - */ -class Piwik_DataTable_Filter_ColumnCallbackDeleteRow extends Piwik_DataTable_Filter -{ - private $columnToFilter; - private $function; - - public function __construct( $table, $columnToFilter, $function ) - { - parent::__construct($table); - $this->function = $function; - $this->columnToFilter = $columnToFilter; - $this->filter(); - } - - protected function filter() - { - foreach($this->table->getRows() as $key => $row) - { - $columnValue = $row->getColumn($this->columnToFilter); - if( $columnValue !== false - && !call_user_func( $this->function, $columnValue)) - { - $this->table->deleteRow($key); - } - } - } -} - diff --git a/modules/DataTable/Filter/ColumnCallbackReplace.php b/modules/DataTable/Filter/ColumnCallbackReplace.php deleted file mode 100644 index 6bdeb73545..0000000000 --- a/modules/DataTable/Filter/ColumnCallbackReplace.php +++ /dev/null @@ -1,42 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_DataTable - */ - -/** - * Replace a column value with a new value resulting - * from the function called with the column's value - * - * @package Piwik_DataTable - * @subpackage Piwik_DataTable_Filter - */ -class Piwik_DataTable_Filter_ColumnCallbackReplace extends Piwik_DataTable_Filter -{ - private $columnToFilter; - private $functionToApply; - - public function __construct( $table, $columnToFilter, $functionToApply ) - { - parent::__construct($table); - $this->functionToApply = $functionToApply; - $this->columnToFilter = $columnToFilter; - $this->filter(); - } - - protected function filter() - { - foreach($this->table->getRows() as $key => $row) - { - $oldValue = $row->getColumn($this->columnToFilter); - $newValue = call_user_func( $this->functionToApply, $oldValue); - $row->setColumn($this->columnToFilter, $newValue); - } - } -} - diff --git a/modules/DataTable/Filter/ExcludeLowPopulation.php b/modules/DataTable/Filter/ExcludeLowPopulation.php deleted file mode 100644 index 7e20776a46..0000000000 --- a/modules/DataTable/Filter/ExcludeLowPopulation.php +++ /dev/null @@ -1,50 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_DataTable - */ - -/** - * Delete all rows that have a $columnToFilter value less than the $minimumValue - * - * For example we delete from the countries report table all countries that have less than 3 visits. - * It is very useful to exclude noise from the reports. - * You can obviously apply this filter on a percentaged column, eg. remove all countries with the column 'percent_visits' less than 0.05 - * - * @package Piwik_DataTable - * @subpackage Piwik_DataTable_Filter - */ -class Piwik_DataTable_Filter_ExcludeLowPopulation extends Piwik_DataTable_Filter -{ - static public $minimumValue; - public function __construct( $table, $columnToFilter, $minimumValue ) - { - $this->columnToFilter = $columnToFilter; - self::$minimumValue = $minimumValue; - parent::__construct($table); - $this->filter(); - } - - function filter() - { - $function = array("Piwik_DataTable_Filter_ExcludeLowPopulation", - "excludeLowPopulation"); - - $filter = new Piwik_DataTable_Filter_ColumnCallbackDeleteRow( - $this->table, - $this->columnToFilter, - $function - ); - } - - static public function excludeLowPopulation($value) - { - return $value >= self::$minimumValue; - } -} - diff --git a/modules/DataTable/Filter/Limit.php b/modules/DataTable/Filter/Limit.php deleted file mode 100644 index 363911fc7d..0000000000 --- a/modules/DataTable/Filter/Limit.php +++ /dev/null @@ -1,58 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_DataTable - */ - -/** - * Delete all rows from the table that are not in the offset,offset+limit range - * - * @package Piwik_DataTable - * @subpackage Piwik_DataTable_Filter - */ - -class Piwik_DataTable_Filter_Limit extends Piwik_DataTable_Filter -{ - /** - * Filter constructor. - * - * @param Piwik_DataTable $table - * @param int $offset Starting row (indexed from 0) - * @param int $limit Number of rows to keep (specify -1 to keep all rows) - */ - public function __construct( $table, $offset, $limit = null ) - { - parent::__construct($table); - $this->offset = $offset; - - if(is_null($limit)) - { - $limit = -1; - } - $this->limit = $limit; - - $this->filter(); - } - - protected function filter() - { - $table = $this->table; - $rowsCount = $table->getRowsCount(); - - // we delete from 0 to offset - $table->deleteRowsOffset( 0, $this->offset ); - - // at this point the array has offset less elements. We delete from limit to the end - if( $this->limit >= 0 ) - { - $table->deleteRowsOffset( $this->limit ); - } - } -} - - diff --git a/modules/DataTable/Filter/MetadataCallbackAddMetadata.php b/modules/DataTable/Filter/MetadataCallbackAddMetadata.php deleted file mode 100644 index 78d9f5f1cc..0000000000 --- a/modules/DataTable/Filter/MetadataCallbackAddMetadata.php +++ /dev/null @@ -1,48 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_DataTable - */ - -/** - * Add a new metadata to the table based on the value resulting - * from a callback function with the parameter being another metadata value - * - * For example for the searchEngine we have a "metadata" information that gives - * the URL of the search engine. We use this URL to add a new "metadata" that gives - * the path of the logo for this search engine URL (which has the format URL.png). - * - * @package Piwik_DataTable - * @subpackage Piwik_DataTable_Filter - */ -class Piwik_DataTable_Filter_MetadataCallbackAddMetadata extends Piwik_DataTable_Filter -{ - private $metadataToRead; - private $functionToApply; - private $metadataToAdd; - - public function __construct( $table, $metadataToRead, $metadataToAdd, $functionToApply ) - { - parent::__construct($table); - $this->functionToApply = $functionToApply; - $this->metadataToRead = $metadataToRead; - $this->metadataToAdd = $metadataToAdd; - $this->filter(); - } - - protected function filter() - { - foreach($this->table->getRows() as $key => $row) - { - $oldValue = $row->getMetadata($this->metadataToRead); - $newValue = call_user_func( $this->functionToApply, $oldValue); - $row->addMetadata($this->metadataToAdd, $newValue); - } - } -} - diff --git a/modules/DataTable/Filter/Null.php b/modules/DataTable/Filter/Null.php deleted file mode 100644 index 680572a6df..0000000000 --- a/modules/DataTable/Filter/Null.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_DataTable - */ - -/** - * Filter template. - * You can use it if you want to create a new filter. - * - * @package Piwik_DataTable - * @subpackage Piwik_DataTable_Filter - */ -class Piwik_DataTable_Filter_Null extends Piwik_DataTable_Filter -{ - - public function __construct( $table ) - { - parent::__construct($table); - $this->filter(); - } - - protected function filter() - { - foreach($this->table->getRows() as $key => $row) - { - } - } -} - diff --git a/modules/DataTable/Filter/Pattern.php b/modules/DataTable/Filter/Pattern.php deleted file mode 100644 index 8ffae09c84..0000000000 --- a/modules/DataTable/Filter/Pattern.php +++ /dev/null @@ -1,44 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_DataTable - */ - -/** - * Delete all rows for which the given $columnToFilter do not contain the $patternToSearch - * This filter is to be used on columns containing strings. - * Exemple: fron the keyword report, keep only the rows for which the label contains "piwik" - * - * @package Piwik_DataTable - * @subpackage Piwik_DataTable_Filter - */ -class Piwik_DataTable_Filter_Pattern extends Piwik_DataTable_Filter -{ - private $columnToFilter; - private $patternToSearch; - - public function __construct( $table, $columnToFilter, $patternToSearch ) - { - parent::__construct($table); - $this->patternToSearch = $patternToSearch; - $this->columnToFilter = $columnToFilter; - $this->filter(); - } - - protected function filter() - { - foreach($this->table->getRows() as $key => $row) - { - if( stripos($row->getColumn($this->columnToFilter), $this->patternToSearch) === false) - { - $this->table->deleteRow($key); - } - } - } -} - diff --git a/modules/DataTable/Filter/PatternRecursive.php b/modules/DataTable/Filter/PatternRecursive.php deleted file mode 100644 index 1faf36a5de..0000000000 --- a/modules/DataTable/Filter/PatternRecursive.php +++ /dev/null @@ -1,77 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_DataTable - */ - -/** - * Delete all rows for which - * - the given $columnToFilter do not contain the $patternToSearch - * - AND all the subTables associated to this row do not contain the $patternToSearch - * - * This filter is to be used on columns containing strings. - * Exemple: from the pages viewed report, keep only the rows that contain "piwik" or for which a subpage contains "piwik". - * - * @package Piwik_DataTable - * @subpackage Piwik_DataTable_Filter - */ -class Piwik_DataTable_Filter_PatternRecursive extends Piwik_DataTable_Filter -{ - private $columnToFilter; - private $patternToSearch; - - public function __construct( $table, $columnToFilter, $patternToSearch ) - { - parent::__construct($table); - $this->patternToSearch = $patternToSearch;//preg_quote($patternToSearch); - $this->columnToFilter = $columnToFilter; - $this->filter(); - } - - protected function filter( $table = null ) - { - if(is_null($table)) - { - $table = $this->table; - } - $rows = $table->getRows(); - - foreach($rows as $key => $row) - { - // A row is deleted if - // 1 - its label doesnt contain the pattern - // AND 2 - the label is not found in the children - $patternNotFoundInChildren = false; - - try{ - $idSubTable = $row->getIdSubDataTable(); - $subTable = Piwik_DataTable_Manager::getInstance()->getTable($idSubTable); - - // we delete the row if we couldn't find the pattern in any row in the - // children hierarchy - if( $this->filter($subTable) == 0 ) - { - $patternNotFoundInChildren = true; - } - } catch(Exception $e) { - // there is no subtable loaded for example - $patternNotFoundInChildren = true; - } - - if( $patternNotFoundInChildren - && (stripos($row->getColumn($this->columnToFilter), $this->patternToSearch) === false) - ) - { - $table->deleteRow($key); - } - } - - return $table->getRowsCount(); - } -} - diff --git a/modules/DataTable/Filter/ReplaceColumnNames.php b/modules/DataTable/Filter/ReplaceColumnNames.php deleted file mode 100644 index 0580c3d3c8..0000000000 --- a/modules/DataTable/Filter/ReplaceColumnNames.php +++ /dev/null @@ -1,93 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_DataTable - */ - -/** - * This filter replaces column names using a mapping table that maps from the old name to the new name. - * - * Why this filter? - * For saving bytes in the database, you can change all the columns labels by an integer value. - * Exemple instead of saving 10000 rows with the column name 'nb_uniq_visitors' which would cost a lot of memory, - * we map it to the integer 1 before saving in the DB. - * After selecting the DataTable from the DB though, you need to restore back the real names so that - * it shows nicely in the report (XML for example). - * - * You can specify the mapping array to apply in the constructor. - * - * @package Piwik_DataTable - * @subpackage Piwik_DataTable_Filter - */ -class Piwik_DataTable_Filter_ReplaceColumnNames extends Piwik_DataTable_Filter -{ - /* - * Old column name => new column name - */ - protected $mappingToApply = array( - Piwik_Archive::INDEX_NB_UNIQ_VISITORS => 'nb_uniq_visitors', - Piwik_Archive::INDEX_NB_VISITS => 'nb_visits', - Piwik_Archive::INDEX_NB_ACTIONS => 'nb_actions', - Piwik_Archive::INDEX_MAX_ACTIONS => 'max_actions', - Piwik_Archive::INDEX_SUM_VISIT_LENGTH => 'sum_visit_length', - Piwik_Archive::INDEX_BOUNCE_COUNT => 'bounce_count', - ); - - /** - * @param DataTable Table - * @param array Mapping to apply. Must have the format - * array( OLD_COLUMN_NAME => NEW_COLUMN NAME, - * OLD_COLUMN_NAME2 => NEW_COLUMN NAME2, - * ) - */ - public function __construct( $table, $mappingToApply = null ) - { - parent::__construct($table); - if(!is_null($mappingToApply)) - { - $this->mappingToApply = $mappingToApply; - } - - $this->filter(); - } - - protected function filter() - { - $this->filterTable($this->table); - } - - protected function filterTable($table) - { - foreach($table->getRows() as $key => $row) - { - $this->renameColumns($row); - - try { - $subTable = Piwik_DataTable_Manager::getInstance()->getTable( $row->getIdSubDataTable() ); - $this->filterTable($subTable); - } catch(Exception $e){ - // case idSubTable == null, or if the table is not loaded in memory - } - } - } - - protected function renameColumns($row) - { - $columns = $row->getColumns(); - foreach($this->mappingToApply as $oldName => $newName) - { - if(isset($columns[$oldName])) - { - $columns[$newName] = $columns[$oldName]; - unset($columns[$oldName]); - } - } - $row->setColumns($columns); - } -} - diff --git a/modules/DataTable/Filter/ReplaceSummaryRowLabel.php b/modules/DataTable/Filter/ReplaceSummaryRowLabel.php deleted file mode 100644 index ed3b627ddc..0000000000 --- a/modules/DataTable/Filter/ReplaceSummaryRowLabel.php +++ /dev/null @@ -1,42 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id: ReplaceColumnNames.php 482 2008-05-18 17:22:35Z matt $ - * - * @package Piwik_DataTable - */ - -/** - * - * @package Piwik_DataTable - * @subpackage Piwik_DataTable_Filter - */ -class Piwik_DataTable_Filter_ReplaceSummaryRowLabel extends Piwik_DataTable_Filter -{ - public function __construct( $table, $newLabel = null) - { - parent::__construct($table); - if(is_null($newLabel)) - { - $newLabel = Piwik_Translate('General_Others'); - } - $this->newLabel = $newLabel; - $this->filter(); - } - - protected function filter() - { - foreach($this->table->getRows() as $row) - { - if($row->getColumn('label') === Piwik_DataTable::LABEL_SUMMARY_ROW) - { - $row->setColumn('label', $this->newLabel); - break; - } - } - } -} - diff --git a/modules/DataTable/Filter/Sort.php b/modules/DataTable/Filter/Sort.php deleted file mode 100644 index 764c050690..0000000000 --- a/modules/DataTable/Filter/Sort.php +++ /dev/null @@ -1,121 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_DataTable - */ - -/** - * Sort the DataTable based on the value of column $columnToSort ordered by $order. - * Possible to specify a natural sorting (see php.net/natsort for details) - * @package Piwik_DataTable - * @subpackage Piwik_DataTable_Filter - */ -class Piwik_DataTable_Filter_Sort extends Piwik_DataTable_Filter -{ - protected $columnToSort; - protected $order; - - public function __construct( $table, $columnToSort, $order = 'desc', $naturalSort = false ) - { - parent::__construct($table); - - // hack... But I can't see how to do properly - if($columnToSort == '0') - { - $columnToSort = 'label'; - } - - $this->columnToSort = $columnToSort; - $this->naturalSort = $naturalSort; - $this->setOrder($order); - $this->filter(); - } - - function setOrder($order) - { - if($order == 'asc') - { - $this->order = 'asc'; - $this->sign = 1; - } - else - { - $this->order = 'desc'; - $this->sign = -1; - } - } - - function sort($a, $b) - { - return $this->sign * - ($a->c[Piwik_DataTable_Row::COLUMNS][$this->columnToSort] - < $b->c[Piwik_DataTable_Row::COLUMNS][$this->columnToSort] - ? -1 - : 1 - ); - } - - function naturalSort($a, $b) - { - return $this->sign * strnatcasecmp( - $a->c[Piwik_DataTable_Row::COLUMNS][$this->columnToSort], - $b->c[Piwik_DataTable_Row::COLUMNS][$this->columnToSort] - ); - } - - - function sortString($a, $b) - { - return $this->sign * - strcasecmp($a->c[Piwik_DataTable_Row::COLUMNS][$this->columnToSort], - $b->c[Piwik_DataTable_Row::COLUMNS][$this->columnToSort] - ); - } - - protected function filter() - { - if($this->table instanceof Piwik_DataTable_Simple) - { - return; - } - $rows = $this->table->getRows(); - - if(count($rows) == 0) - { - return; - } - $row = current($rows); - $value = $row->getColumn($this->columnToSort); - - if($value === false) - { - // we don't throw the exception because we sometimes export a DataTable without a column labelled '2' - // and when the generic filters tries to sort by default using this column 2, this shouldnt raise an exception... - //throw new Exception("The column to sort by '".$this->columnToSort."' is unknown in the row ". implode(array_keys($row->getColumns()), ',')); - return; - } - - if( Piwik::isNumeric($value)) - { - $methodToUse = "sort"; - } - else - { - if($this->naturalSort) - { - $methodToUse = "naturalSort"; - } - else - { - $methodToUse = "sortString"; - } - } - $this->table->sort( array($this,$methodToUse) ); - } -} - diff --git a/modules/DataTable/Manager.php b/modules/DataTable/Manager.php deleted file mode 100644 index 683c35f844..0000000000 --- a/modules/DataTable/Manager.php +++ /dev/null @@ -1,101 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_DataTable - */ - -/** - * The DataTable_Manager registers all the instanciated DataTable and provides an - * easy way to access them. This is used to store all the DataTable during the archiving process. - * At the end of archiving, the ArchiveProcessing will read the stored datatable and record them in the DB. - * - * @package Piwik_DataTable - */ -class Piwik_DataTable_Manager -{ - static private $instance = null; - /** - * Returns instance - * - * @return Piwik_DataTable_Manager - */ - static public function getInstance() - { - if (self::$instance == null) - { - $c = __CLASS__; - self::$instance = new $c(); - } - return self::$instance; - } - - /** - * Array used to store the DataTable - * - * @var array - */ - protected $tables = array(); - - /** - * Add a DataTable to the registry - * - * @param Piwik_DataTable - * @return int Number of tables registered in the manager (including the one just added) - */ - public function addTable( $table ) - { - $this->tables[] = $table; - return count($this->tables) - 1; - } - - /** - * Returns the DataTable associated to the ID $idTable. - * NB: The datatable has to have been instanciated before! - * This method will not fetch the DataTable from the DB. - * - * @exception If the table can't be found - * @return Piwik_DataTable The table - */ - public function getTable( $idTable ) - { - if(!isset($this->tables[$idTable])) - { - throw new Exception(sprintf("The requested table (id = %d) couldn't be found in the DataTable Manager", $idTable)); - } - return $this->tables[$idTable]; - } - - /** - * Delete all the registered DataTables from the manager - * - * @return void - */ - public function deleteAll() - { - $this->tables = array(); - } - - public function deleteTable( $id ) - { - if(isset($this->tables[$id])) - { - $this->tables[$id] = null; - } - } - - /** - * Returns the number of DataTable currently registered. - * - * @return int - */ - public function count() - { - return count($this->tables); - } -} - diff --git a/modules/DataTable/Renderer.php b/modules/DataTable/Renderer.php deleted file mode 100644 index 4d68d8be3e..0000000000 --- a/modules/DataTable/Renderer.php +++ /dev/null @@ -1,104 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_DataTable - */ - -/** - * A DataTable Renderer can produce an output given a DataTable object. - * All new Renderers must be copied in DataTable/Renderer and added to the factory() method. - * To use a renderer, simply do: - * $render = new Piwik_DataTable_Renderer_Xml( $myTable ); - * echo $render; - * - * @package Piwik_DataTable - * @subpackage Piwik_DataTable_Renderer - */ -abstract class Piwik_DataTable_Renderer -{ - protected $table; - protected $renderSubTables; - - /** - * Builds the renderer. - * Works with any kind of DataTable if the renderer used handles this DataTable. - * - * @param Piwik_DataTable|Piwik_DataTable_Simple|Piwik_DataTable_Array $table to be rendered - */ - function __construct($table = null, $renderSubTables = null) - { - if(!is_null($table)) - { - $this->setTable($table); - } - if(is_null($renderSubTables)) - { - $this->renderSubTables = (bool)Piwik_Common::getRequestVar('expanded', false); - } - else - { - $this->renderSubTables = $renderSubTables; - } - } - - /** - * Computes the dataTable output and returns the string/binary - * - * @return string - */ - abstract public function render(); - - /** - * @see render() - * @return string - */ - public function __toString() - { - return $this->render(); - } - - /** - * Set the DataTable to be rendered - * - * @param Piwik_DataTable|Piwik_DataTable_Simple|Piwik_DataTable_Array $table to be rendered - */ - public function setTable($table) - { - if(!($table instanceof Piwik_DataTable) - && !($table instanceof Piwik_DataTable_Array)) - { - throw new Exception("The renderer accepts only a Piwik_DataTable or an array of DataTable (Piwik_DataTable_Array) object."); - } - $this->table = $table; - } - - /** - * Returns the DataTable associated to the output format $name - * - * @throws exception If the renderer is unknown - * @return Piwik_DataTable_Renderer - */ - static public function factory( $name ) - { - $name = ucfirst(strtolower($name)); - $path = "modules/DataTable/Renderer/".$name.".php"; - $className = 'Piwik_DataTable_Renderer_' . $name; - - if( Piwik_Common::isValidFilename($name) - && Zend_Loader::isReadable($path) ) - { - require_once $path; - return new $className; - } - else - { - throw new Exception("Renderer format '$name' not valid. Try 'xml' or 'json' or 'csv' or 'html' or 'php' or 'original' instead."); - } - } -} - diff --git a/modules/DataTable/Renderer/Console.php b/modules/DataTable/Renderer/Console.php deleted file mode 100644 index 481c991a6d..0000000000 --- a/modules/DataTable/Renderer/Console.php +++ /dev/null @@ -1,125 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_DataTable - */ - -/** - * Simple output - * - * @package Piwik_DataTable - * @subpackage Piwik_DataTable_Renderer - */ -class Piwik_DataTable_Renderer_Console extends Piwik_DataTable_Renderer -{ - protected $prefixRows; - function __construct($table = null) - { - parent::__construct($table); - $this->setPrefixRow('#'); - } - - function render() - { - return $this->renderTable($this->table); - } - - function setPrefixRow($str) - { - $this->prefixRows = $str; - } - - protected function renderDataTableArray(Piwik_DataTable_Array $table, $prefix ) - { - $output = "Piwik_DataTable_Array<hr>"; - $prefix = $prefix . ' '; - foreach($table->getArray() as $descTable => $table) - { - $output .= $prefix . "<b>". $descTable. "</b><br>"; - $output .= $prefix . $this->renderTable($table, $prefix . ' '); - $output .= "<hr>"; - } - return $output; - } - - protected function renderTable($table, $prefix = "") - { - if($table instanceof Piwik_DataTable_Array) - { - return $this->renderDataTableArray($table, $prefix); - } - - if($table->getRowsCount() == 0) - { - return "Empty table <br>\n"; - } - - static $depth=0; - $output = ''; - $i = 1; - foreach($table->getRows() as $row) - { - $dataTableArrayBreak = false; - $columns=array(); - foreach($row->getColumns() as $column => $value) - { - if($value instanceof Piwik_DataTable_Array ) - { - $output .= $this->renderDataTableArray($value, $prefix); - $dataTableArrayBreak = true; - break; - } - if(is_string($value)) $value = "'$value'"; - - $columns[] = "'$column' => $value"; - } - if($dataTableArrayBreak === true) - { - continue; - } - $columns = implode(", ", $columns); - - $metadata = array(); - foreach($row->getMetadata() as $name => $value) - { - if(is_string($value)) - { - $value = "'$value'"; - } - $metadata[] = "'$name' => $value"; - } - $metadata = implode(", ", $metadata); - - $output.= str_repeat($this->prefixRows, $depth) - . "- $i [".$columns."] [".$metadata."] [idsubtable = " - . $row->getIdSubDataTable()."]<br>\n"; - - if($row->getIdSubDataTable() !== null) - { - $depth++; - try{ - $output.= $this->renderTable( - Piwik_DataTable_Manager::getInstance()->getTable( - $row->getIdSubDataTable() - ), - $prefix . ' ' - ); - } catch(Exception $e) { - $output.= "-- Sub DataTable not loaded<br>\n"; - } - $depth--; - } - $i++; - } - - return $output; - - } -} - - diff --git a/modules/DataTable/Renderer/Csv.php b/modules/DataTable/Renderer/Csv.php deleted file mode 100644 index 4f2e5a97b2..0000000000 --- a/modules/DataTable/Renderer/Csv.php +++ /dev/null @@ -1,237 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_DataTable - */ - -require_once "DataTable/Renderer/Php.php"; -/** - * CSV export - * - * When rendered using the default settings, a CSV report has the following characteristics: - * The first record contains headers for all the columns in the report. - * All rows have the same number of columns. - * The default field delimiter string is a comma (,). - * Formatting and layout are ignored. - * - * Note that CSV output doesn't handle recursive dataTable. It will output only the first parent level of the tables. - * - * @package Piwik_DataTable - * @subpackage Piwik_DataTable_Renderer - * - */ - -class Piwik_DataTable_Renderer_Csv extends Piwik_DataTable_Renderer -{ - /** - * Column separator - * - * @var string - */ - public $separator = ','; - - /** - * Line end - * - * @var string - */ - public $lineEnd = "\n"; - - /** - * 'metadata' columns will be exported, prefixed by 'metadata_' - * - * @var bool - */ - public $exportMetadata = true; - - /** - * Converts the content to unicode so that UTF8 characters (eg. chinese) can be imported in Excel - * - * @var bool - */ - public $convertToUnicode = true; - - /** - * idSubtable will be exported in a column called 'idsubdatatable' - * - * @var bool - */ - public $exportIdSubtable = true; - - function __construct($table = null) - { - parent::__construct($table); - } - - function render() - { - return $this->renderTable($this->table); - } - - protected function renderTable($table) - { - if($table instanceof Piwik_DataTable_Array) - { - $str = $header = ''; - $prefixColumns = $table->getKeyName() . $this->separator; - foreach($table->getArray() as $currentLinePrefix => $dataTable) - { - $returned = explode("\n",$this->renderTable($dataTable)); - // get the columns names - if(empty($header)) - { - $header = $returned[0]; - } - $returned = array_slice($returned,1); - - // case empty datatable we dont print anything in the CSV export - // when in xml we would output <result date="2008-01-15" /> - if(!empty($returned)) - { - foreach($returned as &$row) - { - $row = $currentLinePrefix . $this->separator . $row; - } - $str .= "\n" . implode("\n", $returned); - } - } - if(!empty($header)) - { - $str = $prefixColumns . $header . $str; - } - } - else - { - $str = $this->renderDataTable($table); - } - - return $this->output($str); - } - - protected function renderDataTable( $table ) - { - if($table instanceof Piwik_DataTable_Simple - && $table->getRowsCount() == 1) - { - $str = 'value' . $this->lineEnd . $table->getRowFromId(0)->getColumn('value'); - return $str; - } - - $csv = array(); - - $allColumns = array(); - foreach($table->getRows() as $row) - { - $csvRow = array(); - - $columns = $row->getColumns(); - foreach($columns as $name => $value) - { - if(!isset($allColumns[$name])) - { - $allColumns[$name] = true; - } - $csvRow[$name] = $value; - } - - if($this->exportMetadata) - { - $metadata = $row->getMetadata(); - foreach($metadata as $name => $value) - { - //if a metadata and a column have the same name make sure they dont overwrite - $name = 'metadata_'.$name; - - $allColumns[$name] = true; - $csvRow[$name] = $value; - } - } - - if($this->exportIdSubtable) - { - $idsubdatatable = $row->getIdSubDataTable(); - if($idsubdatatable !== false) - { - $csvRow['idsubdatatable'] = $idsubdatatable; - } - } - - $csv[] = $csvRow; - } - - // now we make sure that all the rows in the CSV array have all the columns - foreach($csv as &$row) - { - foreach($allColumns as $columnName => $true) - { - if(!isset($row[$columnName])) - { - $row[$columnName] = ''; - } - } - } - $str = ''; - - // specific case, we have only one column and this column wasn't named properly (indexed by a number) - // we don't print anything in the CSV file => an empty line - if(sizeof($allColumns) == 1 - && reset($allColumns) - && !is_string(key($allColumns))) - { - $str .= ''; - } - else - { - $keys = array_keys($allColumns); - $str .= implode($this->separator, $keys); - $str .= $this->lineEnd; - } - - // we render the CSV - foreach($csv as $theRow) - { - $rowStr = ''; - foreach($allColumns as $columnName => $true) - { - $rowStr .= $this->formatValue($theRow[$columnName]) . $this->separator; - } - // remove the last separator - $rowStr = substr_replace($rowStr,"",-strlen($this->separator)); - $str .= $rowStr . $this->lineEnd; - } - $str = substr($str, 0, -strlen($this->lineEnd)); - return $str; - } - - protected function formatValue($value) - { - if(is_string($value) - && !is_numeric($value)) - { - $value = html_entity_decode($value, ENT_COMPAT, 'UTF-8'); - } - return $value; - } - - protected function output( $str ) - { - if(empty($str)) - { - return 'No data available'; - } - // silent fail otherwise unit tests fail - @header("Content-type: application/vnd.ms-excel"); - @header("Content-Disposition: attachment; filename=piwik-report-export.csv"); - if($this->convertToUnicode - && function_exists('mb_convert_encoding')) - { - $str = chr(255) . chr(254) . mb_convert_encoding($str, 'UTF-16LE', 'UTF-8'); - } - return $str; - } -}
\ No newline at end of file diff --git a/modules/DataTable/Renderer/Html.php b/modules/DataTable/Renderer/Html.php deleted file mode 100644 index 84bab607c3..0000000000 --- a/modules/DataTable/Renderer/Html.php +++ /dev/null @@ -1,186 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_DataTable - */ - -/** - * Simple HTML output - * Works with recursive DataTable (when a row can be associated with a subDataTable). - * - * @package Piwik_DataTable - * @subpackage Piwik_DataTable_Renderer - */ -class Piwik_DataTable_Renderer_Html extends Piwik_DataTable_Renderer -{ - protected $prefixRows; - function __construct($table = null) - { - parent::__construct($table); - } - - function render() - { - return $this->renderTable($this->table); - } - - protected function renderTable($table) - { - if($table instanceof Piwik_DataTable_Array) - { - $columnPrefixToAdd = $table->getKeyName(); - $out = "<table border=1>"; - foreach($table->getArray() as $date => $subtable ) - { - $out .= "<tr><td><h2>$columnPrefixToAdd = $date</h2>"; - $out .= $this->renderDataTable($subtable); - $out .= "</td></tr>"; - } - $out .= "</table>"; - } - else - { - $out = $this->renderDataTable($table); - } - return $out; - } - - protected function renderDataTable($table) - { - if($table->getRowsCount() == 0) - { - return "<b><i>Empty table</i></b> <br>\n"; - } - if($table instanceof Piwik_DataTable_Simple - && $table->getRowsCount() ==1) - { - $table->deleteColumn('label'); - } - - static $depth=0; - $i = 1; - $someMetadata = false; - $someIdSubTable = false; - - $tableStructure = array(); - - /* - * table = array - * ROW1 = col1 | col2 | col3 | metadata | idSubTable - * ROW2 = col1 | col2 (no value but appears) | col3 | metadata | idSubTable - * subtable here - */ - $allColumns = array(); - foreach($table->getRows() as $row) - { - foreach($row->getColumns() as $column => $value) - { - $allColumns[$column] = true; - $tableStructure[$i][$column] = $value; - } - - $metadata=array(); - foreach($row->getMetadata() as $name => $value) - { - if(is_string($value)) $value = "'$value'"; - $metadata[] = "'$name' => $value"; - } - - if(count($metadata) != 0) - { - $someMetadata = true; - $metadata = implode("<br>", $metadata); - $tableStructure[$i]['_metadata'] = $metadata; - } - - $idSubtable = $row->getIdSubDataTable(); - if(!is_null($idSubtable)) - { - $someIdSubTable = true; - $tableStructure[$i]['_idSubtable'] = $idSubtable; - } - - if($row->getIdSubDataTable() !== null) - { - $depth++; - try{ - $tableStructure[$i]['_subtable']['html'] = $this->renderTable( Piwik_DataTable_Manager::getInstance()->getTable($row->getIdSubDataTable())); - } catch(Exception $e) { - $tableStructure[$i]['_subtable']['html'] = "-- Sub DataTable not loaded"; - } - $tableStructure[$i]['_subtable']['depth'] = $depth; - $depth--; - } - $i++; - } - - $allColumns['_metadata'] = $someMetadata; - $allColumns['_idSubtable'] = $someIdSubTable; - $html = "\n"; - $html .= "<table border=1 width=70%>"; - $html .= "\n<tr>"; - foreach($allColumns as $name => $toDisplay) - { - if($toDisplay !== false) - { - if($name === 0) - { - $name = 'value'; - } - $html .= "\n\t<td><b>$name</b></td>"; - } - } - $colspan = count($allColumns); - - foreach($tableStructure as $row) - { - $html .= "\n\n<tr>"; - foreach($allColumns as $name => $toDisplay) - { - if($toDisplay !== false) - { - $value = "-"; - if(isset($row[$name])) - { - $value = $row[$name]; - } - - $html .= "\n\t<td>$value</td>"; - } - } - $html .= "</tr>"; - - if(isset($row['_subtable'])) - { - $html .= "<tr> - <td class=l{$row['_subtable']['depth']} colspan=$colspan>{$row['_subtable']['html']}</td></tr>"; - } - } - $html .= "\n\n</table>"; - - // display styles if there is a subtable displayed - if($someIdSubTable) - { - $styles="\n\n<style>\n"; - for($i=0;$i<11;$i++) - { - $padding=$i*2; - $styles.= "\t TD.l$i { padding-left:{$padding}em; } \n"; - } - $styles.="</style>\n\n"; - if($depth == 0) - { - $html = $styles . $html; - } - } - return $html; - } -} - - - diff --git a/modules/DataTable/Renderer/Json.php b/modules/DataTable/Renderer/Json.php deleted file mode 100644 index 5db821c071..0000000000 --- a/modules/DataTable/Renderer/Json.php +++ /dev/null @@ -1,52 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_DataTable - */ - -require_once "DataTable/Renderer/Php.php"; -/** - * JSON export. Using the php 5.2 feature json_encode. - * Works with recursive DataTable (when a row can be associated with a subDataTable). - * - * @package Piwik_DataTable - * @subpackage Piwik_DataTable_Renderer - */ -class Piwik_DataTable_Renderer_Json extends Piwik_DataTable_Renderer -{ - function __construct($table = null, $renderSubTables = null) - { - parent::__construct($table, $renderSubTables); - } - - function render() - { - return $this->renderTable($this->table); - } - - protected function renderTable($table) - { - $renderer = new Piwik_DataTable_Renderer_Php($table, $this->renderSubTables, $serialize = false); - $array = $renderer->flatRender(); - - if(!is_array($array)) - { - $array = array('value' => $array); - } - $str = json_encode($array); - - if(($jsonCallback = Piwik_Common::getRequestVar('jsoncallback', false)) !== false) - { - if(preg_match('/^[0-9a-zA-Z]*$/', $jsonCallback) > 0) - { - $str = $jsonCallback . "(" . $str . ")"; - } - } - return $str; - } -}
\ No newline at end of file diff --git a/modules/DataTable/Renderer/Php.php b/modules/DataTable/Renderer/Php.php deleted file mode 100644 index c23fa0f176..0000000000 --- a/modules/DataTable/Renderer/Php.php +++ /dev/null @@ -1,203 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_DataTable - */ - -/** - * Returns the equivalent PHP array for a given DataTable. - * You can specify in the constructor if you want the serialized version. - * Please note that by default it will produce a flat version of the array. - * See the method flatRender() for details. @see flatRender(); - * - * Works with recursive DataTable (when a row can be associated with a subDataTable). - * - * @package Piwik_DataTable - * @subpackage Piwik_DataTable_Renderer - */ -class Piwik_DataTable_Renderer_Php extends Piwik_DataTable_Renderer -{ - protected $serialize; - - public function __construct($table = null, $renderSubTables = null, $serialize = true) - { - parent::__construct($table, $renderSubTables); - $this->setSerialize($serialize); - } - - public function setSerialize( $bool ) - { - $this->serialize = $bool; - } - - public function __toString() - { - $data = $this->render(); - if(!is_string($data)) - { - $data = serialize($data); - } - return $data; - } - - public function render( $dataTable = null ) - { - if(is_null($dataTable)) - { - $dataTable = $this->table; - } - $toReturn = $this->flatRender( $dataTable ); - - if( false !== Piwik_Common::getRequestVar('prettyDisplay', false) ) - { - if(!is_array($toReturn)) - { - $toReturn = unserialize($toReturn); - } - $toReturn = "<pre>" . var_export($toReturn, true ) . "</pre>"; - } - return $toReturn; - } - - /** - * Produces a flat php array from the DataTable, putting "columns" and "metadata" on the same level. - * - * For example, when a originalRender() would be - * array( 'columns' => array( 'col1_name' => value1, 'col2_name' => value2 ), - * 'metadata' => array( 'metadata1_name' => value_metadata) ) - * - * a flatRender() is - * array( 'col1_name' => value1, - * 'col2_name' => value2, - * 'metadata1_name' => value_metadata ) - * - * @return array Php array representing the 'flat' version of the datatable - * - */ - public function flatRender( $dataTable = null ) - { - if(is_null($dataTable)) - { - $dataTable = $this->table; - } - - if($dataTable instanceof Piwik_DataTable_Array) - { - $flatArray = array(); - foreach($dataTable->getArray() as $keyName => $table) - { - $serializeSave = $this->serialize; - $this->serialize = false; - $flatArray[$keyName] = $this->flatRender($table); - $this->serialize = $serializeSave; - } - } - - // A DataTable_Simple is already flattened so no need to do some crazy stuff to convert it - else if($dataTable instanceof Piwik_DataTable_Simple) - { - $flatArray = $this->renderSimpleTable($dataTable); - - // if we return only one numeric value then we print out the result in a simple <result> tag - // keep it simple! - if(count($flatArray) == 1) - { - $flatArray = current($flatArray); - } - - } - // A normal DataTable needs to be handled specifically - else - { - $array = $this->renderTable($dataTable); - $flatArray = $this->flattenArray($array); - } - - if($this->serialize) - { - $flatArray = serialize($flatArray); - } - - return $flatArray; - } - - protected function flattenArray($array) - { - $flatArray = array(); - foreach($array as $row) - { - $newRow = $row['columns'] + $row['metadata']; - if(isset($row['idsubdatatable'])) - { - $newRow += array('idsubdatatable' => $row['idsubdatatable']); - if(isset($row['subtable'])) - { - $newRow += array('subtable' => $this->flattenArray($row['subtable']) ); - } - } - $flatArray[] = $newRow; - } - return $flatArray; - } - - public function originalRender() - { - if($this->table instanceof Piwik_DataTable_Simple) - { - $array = $this->renderSimpleTable($this->table); - } - else - { - $array = $this->renderTable($this->table); - } - - if($this->serialize) - { - $array = serialize($array); - } - return $array; - } - - protected function renderTable($table) - { - $array = array(); - - foreach($table->getRows() as $row) - { - $newRow = array( - 'columns' => $row->getColumns(), - 'metadata' => $row->getMetadata(), - 'idsubdatatable' => $row->getIdSubDataTable(), - ); - - if($this->renderSubTables - && $row->getIdSubDataTable() !== null) - { - try{ - $subTable = $this->renderTable( Piwik_DataTable_Manager::getInstance()->getTable($row->getIdSubDataTable())); - $newRow['subtable'] = $subTable; - } catch (Exception $e) { - // the subtables are not loaded we dont do anything - } - } - - $array[] = $newRow; - } - return $array; - } - - protected function renderSimpleTable($table) - { - $array = array(); - foreach($table->getRows() as $row) - { - $array[$row->getColumn('label')] = $row->getColumn('value'); - } - return $array; - } -}
\ No newline at end of file diff --git a/modules/DataTable/Renderer/Rss.php b/modules/DataTable/Renderer/Rss.php deleted file mode 100644 index 18574dfcd5..0000000000 --- a/modules/DataTable/Renderer/Rss.php +++ /dev/null @@ -1,169 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id: Html.php 180 2008-01-17 16:32:37Z matt $ - * - * @package Piwik_DataTable - */ - -/** - * RSS Feed. - * The RSS renderer can be used only on Piwik_DataTable_Array that are arrays of Piwik_DataTable. - * A RSS feed contains one dataTable per element in the Piwik_DataTable_Array. - * - * @package Piwik_DataTable - * @subpackage Piwik_DataTable_Renderer - */ -class Piwik_DataTable_Renderer_Rss extends Piwik_DataTable_Renderer -{ - function __construct($table = null) - { - parent::__construct($table); - } - - function render() - { - return $this->renderTable($this->table); - } - - protected function renderTable($table) - { - if(!($table instanceof Piwik_DataTable_Array) - || $table->getKeyName() != 'date') - { - throw new Exception("RSS Feed only used on Piwik_DataTable_Array with keyName = 'date'"); - } - - $idSite = Piwik_Common::getRequestVar('idSite', 1); - $period = Piwik_Common::getRequestVar('period'); - $currentUrl = Piwik_Url::getCurrentUrlWithoutFileName(); - - $piwikUrl = $currentUrl . "?module=CoreHome&action=index&idSite=" . $idSite . "&period=" . $period; - - $out = ""; - $moreRecentFirst = array_reverse($table->getArray(), true); - foreach($moreRecentFirst as $date => $subtable ) - { - $timestamp = $table->metadata[$date]['timestamp']; - $site = $table->metadata[$date]['site']; - - $pudDate = date('r', $timestamp); - $dateUrl = date('Y-m-d', $timestamp); - $thisPiwikUrl = htmlentities($piwikUrl . "&date=$dateUrl"); - $siteName = $site->getName(); - $title = $siteName . " on ". $date; - - $out .= "\t<item> - <pubDate>$pudDate</pubDate> - <guid>$thisPiwikUrl</guid> - <link>$thisPiwikUrl</link> - <title>$title</title> - <author>http://piwik.org</author> - <description>"; - - $out .= htmlspecialchars( $this->renderDataTable($subtable) ); - $out .= "</description>\n\t</item>\n"; - } - - $header = $this->getRssHeader(); - $footer = $this->getRssFooter(); - - return $this->output( $header . $out . $footer); - } - protected function output($str) - { - @header("Content-Type: text/xml;charset=utf-8"); - return $str; - } - protected function getRssFooter() - { - return "\t</channel>\n</rss>"; - } - protected function getRssHeader() - { - $generationDate = date('r'); - $header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> -<rss version=\"2.0\"> - <channel> - <title>piwik statistics - RSS</title> - <link>http://piwik.org</link> - <description>Piwik RSS feed</description> - <pubDate>$generationDate</pubDate> - <generator>piwik</generator> - <language>en</language> - <lastBuildDate>$generationDate</lastBuildDate>"; - return $header; - } - - protected function renderDataTable($table) - { - - if($table->getRowsCount() == 0) - { - return "<b><i>Empty table</i></b> <br>\n"; - } - if($table instanceof Piwik_DataTable_Simple - && $table->getRowsCount() ==1) - { - $table->deleteColumn('label'); - } - - $i = 1; - $tableStructure = array(); - - /* - * table = array - * ROW1 = col1 | col2 | col3 | metadata | idSubTable - * ROW2 = col1 | col2 (no value but appears) | col3 | metadata | idSubTable - * subtable here - */ - $allColumns = array(); - foreach($table->getRows() as $row) - { - foreach($row->getColumns() as $column => $value) - { - $allColumns[$column] = true; - $tableStructure[$i][$column] = $value; - } - $i++; - } - $html = "\n"; - $html .= "<table border=1 width=70%>"; - $html .= "\n<tr>"; - foreach($allColumns as $name => $toDisplay) - { - if($toDisplay !== false) - { - $html .= "\n\t<td><b>$name</b></td>"; - } - } - $html .= "\n</tr>"; - $colspan = count($allColumns); - - foreach($tableStructure as $row) - { - $html .= "\n\n<tr>"; - foreach($allColumns as $name => $toDisplay) - { - if($toDisplay !== false) - { - $value = "-"; - if(isset($row[$name])) - { - $value = urldecode($row[$name]); - } - - $html .= "\n\t<td>$value</td>"; - } - } - $html .= "</tr>"; - - } - $html .= "\n\n</table>"; - return $html; - } -} - diff --git a/modules/DataTable/Renderer/Xml.php b/modules/DataTable/Renderer/Xml.php deleted file mode 100644 index c958f5283d..0000000000 --- a/modules/DataTable/Renderer/Xml.php +++ /dev/null @@ -1,300 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_DataTable - */ - -require_once "DataTable/Renderer/Php.php"; -/** - * XML export of a given DataTable. - * See the tests cases for more information about the XML format (/tests/modules/DataTable/Renderer.test.php) - * Or have a look at the API calls examples. - * - * Works with recursive DataTable (when a row can be associated with a subDataTable). - * - * @package Piwik_DataTable - * @subpackage Piwik_DataTable_Renderer - */ -class Piwik_DataTable_Renderer_Xml extends Piwik_DataTable_Renderer -{ - function __construct($table = null, $renderSubTables = null) - { - parent::__construct($table, $renderSubTables); - } - - function render() - { - return $this->renderTable($this->table); - } - - protected function getArrayFromDataTable($table) - { - $renderer = new Piwik_DataTable_Renderer_Php($table, $this->renderSubTables, $serialize = false); - return $renderer->flatRender(); - } - - protected function renderTable($table, $returnOnlyDataTableXml = false, $prefixLines = '') - { - $array = $this->getArrayFromDataTable($table); - - if($table instanceof Piwik_DataTable_Array) - { - $out = $this->renderDataTableArray($table, $array, $prefixLines); - - if($returnOnlyDataTableXml) - { - return $out; - } - $out = "<results>\n$out</results>"; - return $this->output($out); - } - - // integer value of ZERO is a value we want to display - if($array != 0 && empty($array)) - { - if($returnOnlyDataTableXml) - { - throw new Exception("Illegal state, what xml shall we return?"); - } - $out = "<result />"; - return $this->output($out); - } - if($table instanceof Piwik_DataTable_Simple) - { - if(is_array($array)) - { - $out = $this->renderDataTableSimple($array); - } - else - { - $out = $array; - } - if($returnOnlyDataTableXml) - { - return $out; - } - - if(is_array($array)) - { - $out = "<result>\n".$out."</result>"; - } - else - { - $out = "<result>".$out."</result>"; - } - return $this->output($out); - } - - if($table instanceof Piwik_DataTable) - { - $out = $this->renderDataTable($array); - if($returnOnlyDataTableXml) - { - return $out; - } - $out = "<result>\n$out</result>"; - return $this->output($out); - } - - - } - - protected function renderDataTableArray($table, $array, $prefixLines = "") - { - // CASE 1 - //array - // 'day1' => string '14' (length=2) - // 'day2' => string '6' (length=1) - $firstTable = current($array); - if(!is_array( $firstTable )) - { - $xml = ''; - $nameDescriptionAttribute = $table->getKeyName(); - foreach($array as $valueAttribute => $value) - { - if(empty($value)) - { - $xml .= $prefixLines . "\t<result $nameDescriptionAttribute=\"$valueAttribute\" />\n"; - } - elseif($value instanceof Piwik_DataTable_Array ) - { - $out = $this->renderTable($value, true); - //TODO somehow this code is not tested, cover this case - $xml .= "\t<result $nameDescriptionAttribute=\"$valueAttribute\">\n$out</result>\n"; - } - else - { - $xml .= $prefixLines . "\t<result $nameDescriptionAttribute=\"$valueAttribute\">$value</result>\n"; - } - } - return $xml; - } - - $subTables = $table->getArray(); - $firstTable = current($subTables); - - // CASE 2 - //array - // 'day1' => - // array - // 'nb_uniq_visitors' => string '18' - // 'nb_visits' => string '101' - // 'day2' => - // array - // 'nb_uniq_visitors' => string '28' - // 'nb_visits' => string '11' - if( $firstTable instanceof Piwik_DataTable_Simple) - { - $xml = ''; - $nameDescriptionAttribute = $table->getKeyName(); - foreach($array as $valueAttribute => $dataTableSimple) - { - if(count($dataTableSimple) == 0) - { - $xml .= $prefixLines . "\t<result $nameDescriptionAttribute=\"$valueAttribute\" />\n"; - } - else - { - if(is_array($dataTableSimple)) - { - $dataTableSimple = "\n" . $this->renderDataTableSimple($dataTableSimple, $prefixLines . "\t") . "\t" ; - } - $xml .= $prefixLines . "\t<result $nameDescriptionAttribute=\"$valueAttribute\">".$dataTableSimple. $prefixLines . "</result>\n"; - } - } - return $xml; - } - - // CASE 3 - //array - // 'day1' => - // array - // 0 => - // array - // 'label' => string 'phpmyvisites' - // 'nb_uniq_visitors' => int 11 - // 'nb_visits' => int 13 - // 1 => - // array - // 'label' => string 'phpmyvisits' - // 'nb_uniq_visitors' => int 2 - // 'nb_visits' => int 2 - // 'day2' => - // array - // 0 => - // array - // 'label' => string 'piwik' - // 'nb_uniq_visitors' => int 121 - // 'nb_visits' => int 130 - // 1 => - // array - // 'label' => string 'piwik bis' - // 'nb_uniq_visitors' => int 20 - // 'nb_visits' => int 120 - if($firstTable instanceof Piwik_DataTable) - { - $xml = ''; - $nameDescriptionAttribute = $table->getKeyName(); - foreach($array as $keyName => $arrayForSingleDate) - { - $dataTableOut = $this->renderDataTable( $arrayForSingleDate, $prefixLines . "\t" ); - if(empty($dataTableOut)) - { - $xml .= $prefixLines . "\t<result $nameDescriptionAttribute=\"$keyName\" />\n"; - } - else - { - $xml .= $prefixLines . "\t<result $nameDescriptionAttribute=\"$keyName\">\n"; - $xml .= $dataTableOut; - $xml .= $prefixLines . "\t</result>\n"; - } - } - return $xml; - } - - if($firstTable instanceof Piwik_DataTable_Array) - { - $xml = ''; - $tables = $table->getArray(); - $nameDescriptionAttribute = $table->getKeyName(); - foreach( $tables as $valueAttribute => $tableInArray) - { - $out = $this->renderTable($tableInArray, true, $prefixLines . "\t"); - $xml .= $prefixLines . "\t<result $nameDescriptionAttribute=\"$valueAttribute\">\n".$out.$prefixLines."\t</result>\n"; - - } - return $xml; - } - } - - protected function renderDataTable( $array, $prefixLine = "" ) - { - $out = ''; - foreach($array as $row) - { - $out .= $prefixLine."\t<row>"; - - if(count($row) === 1 - && key($row) === 0) - { - $value = current($row); - $out .= $prefixLine . $value; - } - else - { - $out .= "\n"; - foreach($row as $name => $value) - { - // handle the recursive dataTable case by XML outputting the recursive table - if(is_array($value)) - { - $value = "\n".$this->renderDataTable($value, $prefixLine."\t\t"); - $value .= $prefixLine."\t\t"; - } - else - { - $value = $this->formatValue($value); - } - $out .= $prefixLine."\t\t<$name>".$value."</$name>\n"; - } - $out .= "\t"; - } - $out .= $prefixLine."</row>\n"; - } - return $out; - } - - protected function renderDataTableSimple( $array, $prefixLine = "") - { - $out = ''; - foreach($array as $keyName => $value) - { - $out .= $prefixLine."\t<$keyName>".$this->formatValue($value)."</$keyName>\n"; - } - return $out; - } - - protected function formatValue($value) - { - if(is_string($value) - && !is_numeric($value)) - { - $value = html_entity_decode($value, ENT_COMPAT, 'UTF-8'); - $value = htmlspecialchars($value); - } - return $value; - } - - protected function output( $xml ) - { - // silent fail because otherwise it throws an exception in the unit tests - @header("Content-Type: text/xml;charset=utf-8"); - $xml = '<?xml version="1.0" encoding="utf-8" ?>' . "\n" . $xml; - return $xml; - } -}
\ No newline at end of file diff --git a/modules/DataTable/Row.php b/modules/DataTable/Row.php deleted file mode 100644 index 9ee3bfc9c6..0000000000 --- a/modules/DataTable/Row.php +++ /dev/null @@ -1,404 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_DataTable - */ - -/** - * A DataTable is composed of rows. - * - * A row is composed of: - * - columns often at least a 'label' column containing the description - * of the row, and some numeric values ('nb_visits', etc.) - * - metadata: other information never to be shown as 'columns' - * - idSubtable: a row can be linked to a SubTable - * - * IMPORTANT: Make sure that the column named 'label' contains at least one non-numeric character. - * Otherwise the method addDataTable() or sumRow() would fail because they would consider - * the 'label' as being a numeric column to sum. - * - * @package Piwik_DataTable - * @subpackage Piwik_DataTable_Row - * - */ -class Piwik_DataTable_Row -{ - /** - * This array contains the row information: - * - array indexed by self::COLUMNS contains the columns, pairs of (column names, value) - * - (optional) array indexed by self::METADATA contains the metadata, pairs of (metadata name, value) - * - (optional) integer indexed by self::DATATABLE_ASSOCIATED contains the ID of the Piwik_DataTable associated to this row. - * This ID can be used to read the DataTable from the DataTable_Manager. - * - * @var array - * @see constructor for more information - */ - public $c = array(); - - const COLUMNS = 0; - const METADATA = 1; - const DATATABLE_ASSOCIATED = 3; - - - /** - * Efficient load of the Row structure from a well structured php array - * - * @param array The row array has the structure - * array( - * Piwik_DataTable_Row::COLUMNS => array( - * 'label' => 'Piwik', - * 'column1' => 42, - * 'visits' => 657, - * 'time_spent' => 155744, - * ), - * Piwik_DataTable_Row::METADATA => array( - * 'logo' => 'test.png' - * ), - * Piwik_DataTable_Row::DATATABLE_ASSOCIATED => #Piwik_DataTable object (but in the row only the ID will be stored) - * ) - */ - public function __construct( $row = array() ) - { - $this->c[self::COLUMNS] = array(); - $this->c[self::METADATA] = array(); - $this->c[self::DATATABLE_ASSOCIATED] = null; - - if(isset($row[self::COLUMNS])) - { - $this->c[self::COLUMNS] = $row[self::COLUMNS]; - } - if(isset($row[self::METADATA])) - { - $this->c[self::METADATA] = $row[self::METADATA]; - } - if(isset($row[self::DATATABLE_ASSOCIATED]) - && $row[self::DATATABLE_ASSOCIATED] instanceof Piwik_DataTable) - { - $this->c[self::DATATABLE_ASSOCIATED] = $row[self::DATATABLE_ASSOCIATED]->getId(); - } - } - - /** - * When destroyed, a row destroys its associated subTable if there is one - */ - public function __destruct() - { - $idSubtable = $this->c[self::DATATABLE_ASSOCIATED]; - if($idSubtable !== null) - { - Piwik_DataTable_Manager::getInstance()->deleteTable($idSubtable); - $idSubtable = null; - } - } - - /** - * Applys a basic rendering to the Row and returns the output - * - * @return string characterizing the row. Example: - 1 ['label' => 'piwik', 'nb_uniq_visitors' => 1685, 'nb_visits' => 1861, 'nb_actions' => 2271, 'max_actions' => 13, 'sum_visit_length' => 920131, 'bounce_count' => 1599] [] [idsubtable = 1375] - */ - public function __toString() - { - $columns = array(); - foreach($this->getColumns() as $column => $value) - { - if(is_string($value)) $value = "'$value'"; - $columns[] = "'$column' => $value"; - } - $columns = implode(", ", $columns); - $metadata = array(); - foreach($this->getMetadata() as $name => $value) - { - if(is_string($value)) - { - $name = "'$value'"; - } - $metadata[] = "'$name' => $value"; - } - $metadata = implode(", ", $metadata); - $output = "# [".$columns."] [".$metadata."] [idsubtable = " . $this->getIdSubDataTable()."]<br>\n"; - return $output; - } - - /** - * Deletes the given column - * - * @param string Column name - * @return bool True on success, false if the column didn't exist - */ - public function deleteColumn( $name ) - { - if(!isset($this->c[self::COLUMNS][$name])) - { - return false; - } - unset($this->c[self::COLUMNS][$name]); - return true; - } - - /** - * Returns the given column - * - * @param string Column name - * @return mixed|false The column value - */ - public function getColumn( $name ) - { - if(!isset($this->c[self::COLUMNS][$name])) - { - return false; - } - return $this->c[self::COLUMNS][$name]; - } - - /** - * Returns the array of all metadata, - * or the specified metadata - * - * @param string Metadata name - * @return mixed|array|false - */ - public function getMetadata( $name = null ) - { - if(is_null($name)) - { - return $this->c[self::METADATA]; - } - if(!isset($this->c[self::METADATA][$name])) - { - return false; - } - return $this->c[self::METADATA][$name]; - } - - /** - * Returns the array containing all the columns - * - * @return array Example: array( - * 'column1' => VALUE, - * 'label' => 'www.php.net' - * 'nb_visits' => 15894, - * ) - */ - public function getColumns() - { - return $this->c[self::COLUMNS]; - } - - /** - * Returns the ID of the subDataTable. - * If there is no such a table, returns null. - * - * @return int|null - */ - public function getIdSubDataTable() - { - return $this->c[self::DATATABLE_ASSOCIATED]; - } - - /** - * Sums a DataTable to this row subDataTable. - * If this row doesn't have a SubDataTable yet, we create a new one. - * Then we add the values of the given DataTable to this row's DataTable. - * - * @param Piwik_DataTable Table to sum to this row's subDatatable - * @see Piwik_DataTable::addDataTable() for the algorithm used for the sum - */ - public function sumSubtable(Piwik_DataTable $subTable) - { - $thisSubtableID = $this->getIdSubDataTable(); - if($thisSubtableID === null) - { - $thisSubTable = new Piwik_DataTable; - $this->addSubtable($thisSubTable); - } - else - { - $thisSubTable = Piwik_DataTable_Manager::getInstance()->getTable( $thisSubtableID ); - } - - $thisSubTable->addDataTable($subTable); - } - - - /** - * Set a DataTable to be associated to this row. - * If the row already has a DataTable associated to it, throws an Exception. - * - * @param Piwik_DataTable DataTable to associate to this row - * @throws Exception - * - */ - public function addSubtable(Piwik_DataTable $subTable) - { - if(!is_null($this->c[self::DATATABLE_ASSOCIATED])) - { - throw new Exception("Adding a subtable to the row, but it already has a subtable associated."); - } - $this->c[self::DATATABLE_ASSOCIATED] = $subTable->getId(); - } - - /** - * Set a DataTable to this row. If there is already - * a DataTable associated, it is simply overwritten. - * - * @param Piwik_DataTable DataTable to associate to this row - */ - public function setSubtable(Piwik_DataTable $subTable) - { - $this->c[self::DATATABLE_ASSOCIATED] = $subTable->getId(); - } - - /** - * Set all the columns at once. Overwrites previously set columns. - * - * @param array array( - * 'label' => 'www.php.net' - * 'nb_visits' => 15894, - * ) - */ - public function setColumns( $columns ) - { - $this->c[self::COLUMNS] = $columns; - } - - /** - * Set the value $value to the column called $name. - * - * @param string $name of the column to set - * @param mixed $value of the column to set - */ - public function setColumn($name, $value) - { - if(isset($this->c[self::COLUMNS][$name]) - || $name != 'label') - { - $this->c[self::COLUMNS][$name] = $value; - } - // we make sure when adding the label it goes first in the table - else - { - $this->c[self::COLUMNS] = array($name => $value) + $this->c[self::COLUMNS]; - } - } - - /** - * Add a new column to the row. If the column already exists, throws an exception - * - * @param string $name of the column to add - * @param mixed $value of the column to set - * @throws Exception - */ - public function addColumn($name, $value) - { - if(isset($this->c[self::COLUMNS][$name])) - { - throw new Exception("Column $name already in the array!"); - } - $this->c[self::COLUMNS][$name] = $value; - } - - - /** - * Add a new metadata to the row. If the column already exists, throws an exception. - * - * @param string $name of the metadata to add - * @param mixed $value of the metadata to set - * @throws Exception - */ - public function addMetadata($name, $value) - { - if(isset($this->c[self::METADATA][$name])) - { - throw new Exception("Metadata $name already in the array!"); - } - $this->c[self::METADATA][$name] = $value; - } - - /** - * Sums the given $row columns values to the existing row' columns values. - * It will sum only the int or float values of $row. - * It will not sum the column 'label' even if it has a numeric value. - * - * If a given column doesn't exist in $this then it is added with the value of $row. - * If the column already exists in $this then we have - * this.columns[idThisCol] += $row.columns[idThisCol] - */ - public function sumRow( Piwik_DataTable_Row $rowToSum ) - { - foreach($rowToSum->getColumns() as $name => $value) - { - if($name != 'label' - && Piwik::isNumeric($value)) - { - $current = $this->getColumn($name); - if($current === false) - { - $current = 0; - } - $this->setColumn( $name, $current + $value); - } - } - } - - - /** - * Helper function to test if two rows are equal. - * - * Two rows are equal - * - if they have exactly the same columns / metadata - * - if they have a subDataTable associated, then we check that both of them are the same. - * - * @param Piwik_DataTable_Row row1 to compare - * @param Piwik_DataTable_Row row2 to compare - * - * @return bool - */ - static public function isEqual( Piwik_DataTable_Row $row1, Piwik_DataTable_Row $row2 ) - { - //same columns - $cols1 = $row1->getColumns(); - $cols2 = $row2->getColumns(); - - uksort($cols1, 'strnatcasecmp'); - uksort($cols2, 'strnatcasecmp'); - - if($cols1 != $cols2) - { - return false; - } - - $dets1 = $row1->getMetadata(); - $dets2 = $row2->getMetadata(); - - ksort($dets1); - ksort($dets2); - - if($dets1 != $dets2) - { - return false; - } - - // either both are null - // or both have a value - if( !(is_null($row1->getIdSubDataTable()) - && is_null($row2->getIdSubDataTable()) - ) - ) - { - $subtable1 = Piwik_DataTable_Manager::getInstance()->getTable($row1->getIdSubDataTable()); - $subtable2 = Piwik_DataTable_Manager::getInstance()->getTable($row2->getIdSubDataTable()); - if(!Piwik_DataTable::isEqual($subtable1, $subtable2)) - { - return false; - } - } - return true; - } -} - -require_once "Row/DataTableSummary.php"; diff --git a/modules/DataTable/Row/DataTableSummary.php b/modules/DataTable/Row/DataTableSummary.php deleted file mode 100644 index b6d6e54785..0000000000 --- a/modules/DataTable/Row/DataTableSummary.php +++ /dev/null @@ -1,33 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_DataTable - */ - -/** - * This class creates a row from a given DataTable. - * The row contains - * - for each numeric column, the returned "summary" column is the sum of all the subRows - * - for every other column, it is ignored and will not be in the "summary row" - * - * @see Piwik_DataTable_Row::sumRow() for more information on the algorithm - * - * @package Piwik_DataTable - * @subpackage Piwik_DataTable_Row - */ -class Piwik_DataTable_Row_DataTableSummary extends Piwik_DataTable_Row -{ - function __construct($subTable) - { - parent::__construct(); - foreach($subTable->getRows() as $row) - { - $this->sumRow($row); - } - } -} diff --git a/modules/DataTable/Simple.php b/modules/DataTable/Simple.php deleted file mode 100644 index 04cbb53c70..0000000000 --- a/modules/DataTable/Simple.php +++ /dev/null @@ -1,61 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_DataTable - */ - -/** - * The DataTable_Simple is used to provide an easy way to create simple DataGrid. - * A DataTable_Simple actually is a DataTable with 2 columns: 'label' and 'value'. - * - * It is usually best to return a DataTable_Simple instead of - * a PHP array (or other custom data structure) in API methods: - * - the generic filters can be applied automatically (offset, limit, pattern search, sort, etc.) - * - the renderer can be applied (XML, PHP, HTML, etc.) - * So you don't have to write specific renderer for your data, it is already available in all the formats supported natively by Piwik. - * - * @package Piwik_DataTable - */ -class Piwik_DataTable_Simple extends Piwik_DataTable -{ - /** - * Loads in the DataTable the array information - * @param array Array containing the rows information - * array( - * 'Label row 1' => Value row 1, - * 'Label row 2' => Value row 2, - * ) - * @return void - */ - function loadFromArray($array) - { - foreach($array as $label => $value) - { - $row = new Piwik_DataTable_Row; - $row->addColumn('label', $label); - $row->addColumn('value', $value); - $this->addRow($row); - } - } - - /** - * Returns the 'value' column of the row that has a label '$label'. - * - * @param string Label of the row we want the value - * @return false|mixed The 'value' column of the row labelled $label - */ - function getColumn( $label ) - { - $row = $this->getRowFromLabel($label); - if($row === false) - { - return false; - } - return $row->getColumn('value'); - } -} diff --git a/modules/Date.php b/modules/Date.php deleted file mode 100644 index 9ad0f18539..0000000000 --- a/modules/Date.php +++ /dev/null @@ -1,341 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_Helper - */ - -/** - * Date object widely used in Piwik. - * - * @package Piwik_Helper - */ -class Piwik_Date -{ - /** - * Returns a Piwik_Date objects. - * Accepts strings 'today' 'yesterday' or any YYYY-MM-DD or timestamp - * - * @param string $strDate - * @return Piwik_Date - */ - static public function factory($strDate) - { - if(is_int($strDate)) - { - return new Date($strDate); - } - if(is_string($strDate)) - { - if($strDate == 'today') - { - return self::today(); - } - elseif($strDate == 'yesterday') - { - return self::yesterday(); - } - else - { - if (($timestamp = strtotime($strDate)) === false) - { - throw new Exception("The date '$strDate' is not correct. The date format is YYYY-MM-DD or you can also use magic keywords such as 'today' or 'yesterday' or any keyword supported by the strtotime function (see http://php.net/strtotime for more information)"); - } - return new Piwik_Date($timestamp); - } - } - } - - /** - * Builds a Piwik_Date object - * - * @param int timestamp - */ - public function __construct( $date ) - { - if(!is_int( $date )) - { - throw new Exception("Piwik_Date is expecting a unix timestamp"); - } - $this->timestamp = $date ; - } - - /** - * Sets the time part of the date - * Doesn't modify $this - * - * @param string $time HH:MM:SS - * @return Piwik_Date The new date with the time part set - */ - //TODO test this method - public function setTime($time) - { - return new Piwik_Date( strtotime( $this->get("j F Y") . " $time")); - } - - /** - * Returns the unix timestamp of the date - * - * @return int - */ - public function getTimestamp() - { - return $this->timestamp; - } - - /** - * Returns true if the current date is older than the given $date - * - * @param Piwik_Date $date - * @return bool - */ - public function isLater( Piwik_Date $date) - { - return $this->getTimestamp() > $date->getTimestamp(); - } - - /** - * Returns true if the current date is earlier than the given $date - * - * @param Piwik_Date $date - * @return bool - */ - public function isEarlier(Piwik_Date $date) - { - return $this->getTimestamp() < $date->getTimestamp(); - } - - /** - * Returns the Y-m-d representation of the string. - * You can specify the output, see the list on php.net/date - * - * @param string $part - * @return string - */ - public function toString($part = 'Y-m-d') - { - return date($part, $this->getTimestamp()); - } - - /** - * @see toString() - * - * @return string - */ - public function __toString() - { - return $this->toString(); - } - - /** - * Sets a new day - * Returned is the new date object - * Doesn't modify $this - * - * @param int Day eg. 31 - * @return Piwik_Date new date - */ - public function setDay( $day ) - { - $ts = $this->getTimestamp(); - $result = mktime( - date('H', $ts), - date('i', $ts), - date('s', $ts), - date('n', $ts), - 1, - date('Y', $ts) - ); - return new Piwik_Date( $result ); - } - - /** - * Sets a new year - * Returned is the new date object - * Doesn't modify $this - * - * @param int 2010 - * @return Piwik_Date new date - */ - public function setYear( $year ) - { - $ts = $this->getTimestamp(); - $result = mktime( - date('H', $ts), - date('i', $ts), - date('s', $ts), - date('n', $ts), - date('j', $ts), - $year - ); - return new Piwik_Date( $result ); - } - - - - /** - * Subtracts days from the existing date object and returns a new Piwik_Date object - * Doesn't modify $this - * - * Returned is the new date object - * @return Piwik_Date new date - */ - public function subDay( $n ) - { - if($n === 0) - { - return clone $this; - } - $ts = strtotime("-$n day", $this->getTimestamp()); - return new Piwik_Date( $ts ); - } - - /** - * Subtracts a month from the existing date object. - * Returned is the new date object - * Doesn't modify $this - * - * @return Piwik_Date new date - */ - public function subMonth( $n ) - { - if($n === 0) - { - return clone $this; - } - $ts = $this->getTimestamp(); - $result = mktime( - date('H', $ts), - date('i', $ts), - date('s', $ts), - date('n', $ts) - $n, - 1, // we set the day to 1 - date('Y', $ts) - ); - return new Piwik_Date( $result ); - } - - /** - * Returns a representation of a date or datepart - * - * @param string OPTIONAL Part of the date to return, if null the timestamp is returned - * @return integer|string date or datepart - */ - public function get($part = null) - { - if(is_null($part)) - { - return $this->getTimestamp(); - } - return date($part, $this->getTimestamp()); - } - - /** - * Returns a localized representation of a date or datepart - * - * @param string OPTIONAL Part of the date to return (in strftime format), if null timestamp is returned - * @return integer|string date or datepart - */ - public function getLocalized($part = null) - { - if(is_null($part)) - { - return $this->getTimestamp(); - } - return strftime($part, $this->getTimestamp()); - } - - /** - * Adds days to the existing date object. - * Returned is the new date object - * Doesn't modify $this - * - * @param int Number of days to add - * @return Piwik_Date new date - */ - public function addDay( $n ) - { - $ts = strtotime("+$n day", $this->getTimestamp()); - return new Piwik_Date( $ts ); - } - - /** - * Compares the week of the current date against the given $date - * Returns 0 if equal, -1 if current week is earlier or 1 if current week is later - * Example: 09.Jan.2007 13:07:25 -> compareWeek(2); -> 0 - * - * @param Piwik_Date $date - * @return integer 0 = equal, 1 = later, -1 = earlier - */ - public function compareWeek(Piwik_Date $date) - { - $currentWeek = date('W', $this->getTimestamp()); - $toCompareWeek = date('W', $date->getTimestamp()); - if( $currentWeek == $toCompareWeek) - { - return 0; - } - if( $currentWeek < $toCompareWeek) - { - return -1; - } - return 1; - } - /** - * Compares the month of the current date against the given $date month - * Returns 0 if equal, -1 if current month is earlier or 1 if current month is later - * For example: 10.03.2000 -> 15.03.1950 -> 0 - * - * @param Piwik_Date $month Month to compare - * @return integer 0 = equal, 1 = later, -1 = earlier - */ - function compareMonth( Piwik_Date $date ) - { - $currentMonth = date('n', $this->getTimestamp()); - $toCompareMonth = date('n', $date->getTimestamp()); - if( $currentMonth == $toCompareMonth) - { - return 0; - } - if( $currentMonth < $toCompareMonth) - { - return -1; - } - return 1; - } - - /** - * Returns true if current date is today - * - * @return bool - */ - public function isToday() - { - return $this->get('Y-m-d') === date('Y-m-d', time()); - } - - /** - * Returns a date object set to today midnight - * - * @return Piwik_Date - */ - static public function today() - { - return new Piwik_Date(strtotime(date("Y-m-d 00:00:00"))); - } - - /** - * Returns a date object set to yesterday midnight - * @return Piwik_Date - */ - static public function yesterday() - { - return new Piwik_Date(strtotime("yesterday")); - } - -} - diff --git a/modules/ErrorHandler.php b/modules/ErrorHandler.php deleted file mode 100755 index bd34a019cc..0000000000 --- a/modules/ErrorHandler.php +++ /dev/null @@ -1,68 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_Helper - */ - -require_once "Zend/Registry.php"; - -if(!defined('E_STRICT')) define('E_STRICT', 2048); -if(!defined('E_RECOVERABLE_ERROR')) define('E_RECOVERABLE_ERROR', 4096); -if(!defined('E_EXCEPTION')) define('E_EXCEPTION', 8192); - -/** - * Error handler used to display nicely errors in Piwik - * - * @package Piwik_Helper - */ -function Piwik_ErrorHandler($errno, $errstr, $errfile, $errline) -{ - // if the error has been suppressed by the @ we don't handle the error - if( error_reporting() == 0 ) - { - return; - } - - ob_start(); - debug_print_backtrace(); - $backtrace = ob_get_contents(); - ob_end_clean(); - - - try { - Zend_Registry::get('logger_error')->log($errno, $errstr, $errfile, $errline, $backtrace); - }catch(Exception $e){ - // in case the error occurs before the logger creation, we simply display it - print("<pre>$errstr \nin '$errfile' at the line $errline\n\n$backtrace\n</pre>"); - exit; - } - switch($errno) - { - case E_ERROR: - case E_PARSE: - case E_CORE_ERROR: - case E_CORE_WARNING: - case E_COMPILE_ERROR: - case E_COMPILE_WARNING: - case E_USER_ERROR: - case E_EXCEPTION: - exit; - break; - - case E_WARNING: - case E_NOTICE: - case E_USER_WARNING: - case E_USER_NOTICE: - case E_STRICT: - case E_RECOVERABLE_ERROR: - default: - // do not exit - break; - } -} - diff --git a/modules/ExceptionHandler.php b/modules/ExceptionHandler.php deleted file mode 100644 index 7cebb85908..0000000000 --- a/modules/ExceptionHandler.php +++ /dev/null @@ -1,43 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_Helper - */ - -require_once "modules/Piwik.php"; - -/** - * Exception handler used to display nicely exceptions in Piwik - * - * @package Piwik_Helper - */ -function Piwik_ExceptionHandler(Exception $exception) -{ - try { - Zend_Registry::get('logger_exception')->log($exception); - } catch(Exception $e) { - // case when the exception is raised before the logger being ready - // we handle the exception a la mano, but using the Logger formatting properties - require_once "Log/Exception.php"; - - $event = array(); - $event['errno'] = $exception->getCode(); - $event['message'] = $exception->getMessage(); - $event['errfile'] = $exception->getFile(); - $event['errline'] = $exception->getLine(); - $event['backtrace'] = $exception->getTraceAsString(); - - $formatter = new Piwik_Log_Formatter_Exception_ScreenFormatter; - - $message = $formatter->format($event); - $message .= "<br><br>And this exception raised another exception \"". $e->getMessage()."\""; - - Piwik::exitWithErrorMessage( $message ); - } -} - diff --git a/modules/Form.php b/modules/Form.php deleted file mode 100644 index de7f85220d..0000000000 --- a/modules/Form.php +++ /dev/null @@ -1,101 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_Helper - */ - - -require_once "HTML/QuickForm.php"; -require_once "HTML/QuickForm/Renderer/ArraySmarty.php"; - -/** - * Parent class for forms to be included in Smarty - * - * For an example, @see Piwik_Login_Form - * - * @package Piwik_Helper - */ -abstract class Piwik_Form extends HTML_QuickForm -{ - protected $a_formElements = array(); - - function __construct( $action = '' ) - { - if(empty($action)) - { - $action = Piwik_Url::getCurrentUrl(); - } - parent::HTML_QuickForm('form', 'POST', $action); - - $this->registerRule( 'checkEmail', 'function', 'Piwik_Form_isValidEmailString'); - $this->registerRule( 'fieldHaveSameValue', 'function', 'Piwik_Form_fieldHaveSameValue'); - - $this->init(); - } - - abstract function init(); - - function getElementList() - { - $listElements=array(); - foreach($this->a_formElements as $title => $a_parameters) - { - foreach($a_parameters as $parameters) - { - if($parameters[1] != 'headertext' - && $parameters[1] != 'submit') - { - // case radio : there are two labels but only record once, unique name - if( !isset($listElements[$title]) - || !in_array($parameters[1], $listElements[$title])) - { - $listElements[$title][] = $parameters[1]; - } - } - } - } - return $listElements; - } - - function addElements( $a_formElements, $sectionTitle = '' ) - { - foreach($a_formElements as $parameters) - { - call_user_func_array(array(&$this , "addElement"), $parameters ); - } - - $this->a_formElements = - array_merge( - $this->a_formElements, - array( - $sectionTitle => $a_formElements - ) - ); - } - - function addRules( $a_formRules) - { - foreach($a_formRules as $parameters) - { - call_user_func_array(array(&$this , "addRule"), $parameters ); - } - - } - -} - -function Piwik_Form_fieldHaveSameValue($element, $value, $arg) -{ - $value2 = Piwik_Common::getRequestVar( $arg, '', 'string'); - return $value === $value2; -} - -function Piwik_Form_isValidEmailString( $element, $value ) -{ - return Piwik::isValidEmailString($value); -}
\ No newline at end of file diff --git a/modules/FrontController.php b/modules/FrontController.php deleted file mode 100644 index aca0de9a95..0000000000 --- a/modules/FrontController.php +++ /dev/null @@ -1,316 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik - */ - - -/** - * Zend classes - */ -require_once "Zend/Exception.php"; -require_once "Zend/Loader.php"; -require_once "Zend/Auth.php"; -require_once "Zend/Auth/Adapter/DbTable.php"; - -/** - * Piwik classes - */ -require_once "Timer.php"; -require_once "modules/Piwik.php"; -require_once "API/APIable.php"; -require_once "Access.php"; -require_once "Auth.php"; -require_once "API/Proxy.php"; -require_once "Site.php"; -require_once "Translate.php"; -require_once "Mail.php"; -require_once "Url.php"; -require_once "Controller.php"; - -require_once "PluginsFunctions/Menu.php"; -require_once "PluginsFunctions/AdminMenu.php"; -require_once "PluginsFunctions/Widget.php"; -require_once "PluginsFunctions/Sql.php"; - -/** - * Front controller. - * This is the class hit in the first place. - * It dispatches the request to the right controller. - * - * For a detailed explanation, see the documentation on http://dev.piwik.org/trac/wiki/MainSequenceDiagram - * - * @package Piwik - */ -class Piwik_FrontController -{ - /** - * Set to false and the Front Controller will not dispatch the request - * - * @var bool - */ - static public $enableDispatch = true; - - static private $instance = null; - - /** - * returns singleton - * - * @return Piwik_FrontController - */ - static public function getInstance() - { - if (self::$instance == null) - { - $c = __CLASS__; - self::$instance = new $c(); - } - return self::$instance; - } - - /** - * Dispatches the request to the right plugin and executes the requested action on the plugin controller. - * - * @throws Exception in case the plugin doesn't exist, the action doesn't exist, there is not enough permission, etc. - * - * @param string $module - * @param string $action - * @param array $parameters - * @return mixed The returned value of the calls, often nothing as the module print but don't return data - * @see fetchDispatch() - */ - function dispatch( $module = null, $action = null, $parameters = null) - { - if( self::$enableDispatch === false) - { - return; - } - - if(is_null($module)) - { - $defaultModule = 'CoreHome'; - $module = Piwik_Common::getRequestVar('module', $defaultModule, 'string'); - } - - if(is_null($action)) - { - $action = Piwik_Common::getRequestVar('action', false); - } - - if(is_null($parameters)) - { - $parameters = array(); - } - - if(!ctype_alnum($module)) - { - throw new Exception("Invalid module name '$module'"); - } - - if( ! Piwik_PluginsManager::getInstance()->isPluginEnabled( $module )) - { - throw new Exception_PluginDeactivated($module); - } - - $controllerClassName = "Piwik_".$module."_Controller"; - if(!class_exists($controllerClassName)) - { - $moduleController = "plugins/" . $module . "/Controller.php"; - if( !Zend_Loader::isReadable($moduleController)) - { - throw new Exception("Module controller $moduleController not found!"); - } - require_once $moduleController; - } - - $controller = new $controllerClassName; - if($action === false) - { - $action = $controller->getDefaultAction(); - } - - if( !is_callable(array($controller, $action))) - { - throw new Exception("Action $action not found in the controller $controllerClassName."); - } - - try { - return call_user_func_array( array($controller, $action ), $parameters); - } catch(Piwik_Access_NoAccessException $e) { - Piwik_PostEvent('FrontController.NoAccessException', $e); - } - } - - /** - * Often plugins controller display stuff using echo/print. - * Using this function instead of dispath() returns the output string form the actions calls. - * - * @param string $controllerName - * @param string $actionName - * @param array $parameters - * @return string - */ - function fetchDispatch( $controllerName = null, $actionName = null, $parameters = null) - { - ob_start(); - $output = $this->dispatch( $controllerName, $actionName, $parameters); - // if nothing returned we try to load something that was printed on the screen - if(empty($output)) - { - $output = ob_get_contents(); - } - ob_end_clean(); - return $output; - } - - /** - * Called at the end of the page generation - * - */ - function __destruct() - { - try { - Piwik::printSqlProfilingReportZend(); - Piwik::printQueryCount(); - } catch(Exception $e) {} - - if(Piwik::getModule() !== 'API') - { -// Piwik::printMemoryUsage(); -// Piwik::printTimer(); - } - } - - /** - * Checks that the directories Piwik needs write access are actually writable - * Displays a nice error page if permissions are missing on some directories - * - * @return void - */ - static public function checkDirectoriesWritableOrDie( $directoriesToCheck = null ) - { - $resultCheck = Piwik::checkDirectoriesWritable( $directoriesToCheck ); - if( array_search(false, $resultCheck) !== false ) - { - $directoryList = ''; - foreach($resultCheck as $dir => $bool) - { - $realpath = Piwik::realpath($dir); - if(!empty($realpath) && $bool === false) - { - $directoryList .= "<code>chmod 777 $realpath</code><br>"; - } - } - $directoryList .= ''; - $directoryMessage = "<p><b>Piwik couldn't write to some directories</b>.</p> <p>Try to Execute the following commands on your Linux server:</P>"; - $directoryMessage .= $directoryList; - $directoryMessage .= "<p>If this doesn't work, you can try to create the directories with your FTP software, and set the CHMOD to 777 (with your FTP software, right click on the directories, permissions)."; - $directoryMessage .= "<p>After applying the modifications, you can <a href='index.php'>refresh the page</a>."; - $directoryMessage .= "<p>If you need more help, try <a href='misc/redirectToUrl.php?url=http://piwik.org'>Piwik.org</a>."; - - Piwik_ExitWithMessage($directoryMessage); - } - } - - /** - * Must be called before dispatch() - * - checks that directories are writable, - * - loads the configuration file, - * - loads the plugin, - * - inits the DB connection, - * - etc. - * - * @return void - */ - function init() - { - try { - Zend_Registry::set('timer', new Piwik_Timer); - - $directoriesToCheck = array( - '/tmp', - '/tmp/templates_c', - '/tmp/cache', - ); - - self::checkDirectoriesWritableOrDie($directoriesToCheck); - self::assignCliParametersToRequest(); - - $exceptionToThrow = false; - - try { - Piwik::createConfigObject(); - } catch(Exception $e) { - Piwik_PostEvent('FrontController.NoConfigurationFile', $e); - $exceptionToThrow = $e; - } - - Piwik::loadPlugins(); - if($exceptionToThrow) - { - throw $exceptionToThrow; - } - Piwik::createDatabaseObject(); - Piwik::createLogObject(); - Piwik::installLoadedPlugins(); - Piwik::install(); - - Piwik_PostEvent('FrontController.initAuthenticationObject'); - try { - $authAdapter = Zend_Registry::get('auth'); - } catch(Exception $e){ - throw new Exception("Object 'auth' cannot be found in the Registry. Maybe the Login plugin is not enabled? - <br>You can enable the plugin by adding:<br> - <code>Plugins[] = Login</code><br> - under the <code>[Plugins]</code> section in your config/config.inc.php"); - } - - $access = new Piwik_Access($authAdapter); - Zend_Registry::set('access', $access); - Zend_Registry::get('access')->loadAccess(); - - Piwik::raiseMemoryLimitIfNecessary(); - } catch(Exception $e) { - Piwik_ExitWithMessage($e->getMessage()); - } - } - - /** - * Assign CLI parameters as if they were REQUEST or GET parameters. - * You can trigger Piwik from the command line by - * # /usr/bin/php5 /path/to/piwik/index.php -- "module=API&method=Actions.getActions&idSite=1&period=day&date=previous8&format=php" - * - * @return void - */ - static protected function assignCliParametersToRequest() - { - if(isset($_SERVER['argc']) - && $_SERVER['argc'] > 0) - { - for ($i=1; $i < $_SERVER['argc']; $i++) - { - parse_str($_SERVER['argv'][$i],$tmp); - $_REQUEST = array_merge($_REQUEST, $tmp); - $_GET = array_merge($_GET, $tmp); - } - } - } -} - -/** - * Exception thrown when the requested plugin is not activated in the config file - * - * @package Piwik - */ -class Exception_PluginDeactivated extends Exception -{ - function __construct($module) - { - parent::__construct("The plugin '$module' is not enabled. You can activate the plugin on the <a href='?module=CoreAdminHome&action=showInContext&moduleToLoad=CorePluginsAdmin'>Plugins admin page</a>."); - } -} diff --git a/modules/Log.php b/modules/Log.php deleted file mode 100755 index c793d6d2db..0000000000 --- a/modules/Log.php +++ /dev/null @@ -1,162 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_Log - */ - -require_once "Zend/Log.php"; -require_once "Zend/Log/Formatter/Interface.php"; -require_once "Zend/Log/Writer/Stream.php"; -require_once "Zend/Log/Writer/Db.php"; - -require_once "Common.php"; - -/** - * - * @package Piwik_Log - */ -abstract class Piwik_Log extends Zend_Log -{ - protected $logToDatabaseTableName = null; - protected $logToDatabaseColumnMapping = null; - protected $logToFileFilename = null; - protected $fileFormatter = null; - protected $screenFormatter = null; - - function __construct( $logToFileFilename, - $fileFormatter, - $screenFormatter, - $logToDatabaseTableName, - $logToDatabaseColumnMapping ) - { - parent::__construct(); - - - $this->logToFileFilename = Zend_Registry::get('config')->path->log . $logToFileFilename; - $this->fileFormatter = $fileFormatter; - $this->screenFormatter = $screenFormatter; - $this->logToDatabaseTableName = Piwik::prefixTable($logToDatabaseTableName); - $this->logToDatabaseColumnMapping = $logToDatabaseColumnMapping; - } - - static public function dump($var) - { - Zend_Registry::get('logger_message')->log(var_export($var, true), Piwik_Log::DEBUG); - } - - function addWriteToFile() - { - $writerFile = new Zend_Log_Writer_Stream($this->logToFileFilename); - Piwik::mkdir(Zend_Registry::get('config')->path->log); - $writerFile->setFormatter( $this->fileFormatter ); - $this->addWriter($writerFile); - } - - function addWriteToNull() - { - Zend_Loader::loadClass('Zend_Log_Writer_Null'); - $this->addWriter( new Zend_Log_Writer_Null ); - } - - function addWriteToDatabase() - { - $writerDb = new Zend_Log_Writer_Db( - Zend_Registry::get('db'), - $this->logToDatabaseTableName, - $this->logToDatabaseColumnMapping); - - $this->addWriter($writerDb); - } - - function addWriteToScreen() - { - $writerScreen = new Zend_Log_Writer_Stream('php://output'); - $writerScreen->setFormatter( $this->screenFormatter ); - $this->addWriter($writerScreen); - } - - public function getWritersCount() - { - return count($this->_writers); - } - - /** - * Log an event - * Overload Zend_log::log - */ - public function log($event) - { - // sanity checks - if (empty($this->_writers)) { - throw new Zend_Log_Exception('No writers were added'); - } - - $event['timestamp'] = date('c'); - - // pack into event required by filters and writers - $event = array_merge( $event, $this->_extras); - - // abort if rejected by the global filters - foreach ($this->_filters as $filter) { - if (! $filter->accept($event)) { - return; - } - } - - // send to each writer - foreach ($this->_writers as $writer) { - $writer->write($event); - } - } - -} - -/** - * - * - * @package Piwik_Log - */ -class Piwik_Log_Formatter_FileFormatter implements Zend_Log_Formatter_Interface -{ - /** - * Formats data into a single line to be written by the writer. - * - * @param array $event event data - * @return string formatted line to write to the log - */ - public function format($event) - { - foreach($event as &$value) - { - $value = str_replace("\n", '\n', $value); - $value = '"'.$value.'"'; - } - $str = implode(" ", $event) . "\n"; - return $str; - } -} - -class Piwik_Log_Formatter_ScreenFormatter implements Zend_Log_Formatter_Interface -{ - function format($string) - { - $string = self::getFormattedString($string); - return $string; - } - - static public function getFormattedString($string) - { - if(Piwik::isPhpCliMode()) - { - $string = str_replace(array('<br>','<br />','<br/>'), "\n", $string); - $string = strip_tags($string); - } - return $string; - } -} - diff --git a/modules/Log/APICall.php b/modules/Log/APICall.php deleted file mode 100644 index ab6f7207bd..0000000000 --- a/modules/Log/APICall.php +++ /dev/null @@ -1,118 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_Log - * @subpackage Piwik_Log_APICall - */ - -/** - * 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'; - - function __construct() - { - $logToFileFilename = self::ID; - $logToDatabaseTableName = self::ID; - $logToDatabaseColumnMapping = null; - $screenFormatter = new Piwik_Log_Formatter_APICall_ScreenFormatter; - $fileFormatter = new Piwik_Log_Formatter_FileFormatter; - - parent::__construct($logToFileFilename, - $fileFormatter, - $screenFormatter, - $logToDatabaseTableName, - $logToDatabaseColumnMapping ); - - $this->setEventItem('caller_ip', ip2long( Piwik_Common::getIp() ) ); - } - - function log( $className, $methodName, $parameterNames, $parameterValues, $executionTime, $returnedValue) - { - $event = array(); - $event['class_name'] = $className; - $event['method_name'] = $methodName; - $event['parameter_names_default_values'] = serialize($parameterNames); - $event['parameter_values'] = serialize($parameterValues); - $event['execution_time'] = $executionTime; - $event['returned_value'] = is_array($returnedValue) ? serialize($returnedValue) : $returnedValue; - - parent::log($event); - } -} - -/** - * Class used to format the API Call log on the screen. - * - * @package Piwik_Log - * @subpackage Piwik_Log_APICall - */ -class Piwik_Log_Formatter_APICall_ScreenFormatter extends Piwik_Log_Formatter_ScreenFormatter -{ - /** - * Formats data into a single line to be written by the writer. - * - * @param array $event event data - * @return string formatted line to write to the log - */ - public function format($event) - { - $str = "\n<br> "; - $str .= "Called: {$event['class_name']}.{$event['method_name']} (took {$event['execution_time']}ms) \n<br>"; - $str .= "Parameters: "; - $parameterNamesAndDefault = unserialize($event['parameter_names_default_values']); - $parameterValues = unserialize($event['parameter_values']); - - $i = 0; - foreach($parameterNamesAndDefault as $pName => $pDefault) - { - if(isset($parameterValues[$i])) - { - $currentValue = $parameterValues[$i]; - } - else - { - $currentValue = $pDefault; - } - - $currentValue = $this->formatValue($currentValue); - $str .= "$pName = $currentValue, "; - - $i++; - } - $str .= "\n<br> "; - -// $str .= "Returned: ".$this->formatValue($event['returned_value']); - $str .= "\n<br> "; - return parent::format($str); - } - - private function formatValue( $value ) - { - if(is_string($value)) - { - $value = "'$value'"; - } - if(is_null($value)) - { - $value= 'null'; - } - if(is_array($value)) - { - $value = "array( ".implode(", ", $value). ")"; - } - return $value; - - } -} - diff --git a/modules/Log/Error.php b/modules/Log/Error.php deleted file mode 100644 index 84b2bbf9ef..0000000000 --- a/modules/Log/Error.php +++ /dev/null @@ -1,118 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_Log - * @subpackage Piwik_Log_Error - */ - -/** - * 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'; - function __construct() - { - $logToFileFilename = self::ID; - $logToDatabaseTableName = self::ID; - $logToDatabaseColumnMapping = null; - $screenFormatter = new Piwik_Log_Formatter_Error_ScreenFormatter; - $fileFormatter = new Piwik_Log_Formatter_FileFormatter; - - parent::__construct($logToFileFilename, - $fileFormatter, - $screenFormatter, - $logToDatabaseTableName, - $logToDatabaseColumnMapping ); - } - - function addWriteToScreen() - { - parent::addWriteToScreen(); - $writerScreen = new Zend_Log_Writer_Stream('php://stderr'); - $writerScreen->setFormatter( $this->screenFormatter ); - $this->addWriter($writerScreen); - } - - public function log($errno, $errstr, $errfile, $errline, $backtrace) - { - $event = array(); - $event['errno'] = $errno; - $event['message'] = $errstr; - $event['errfile'] = $errfile; - $event['errline'] = $errline; - $event['backtrace'] = $backtrace; - - parent::log($event); - } -} - - - -/** - * Format an error event to be displayed on the screen. - * - * @package Piwik_Log - * @subpackage Piwik_Log_Error - */ -class Piwik_Log_Formatter_Error_ScreenFormatter extends Piwik_Log_Formatter_ScreenFormatter -{ - /** - * Formats data into a single line to be written by the writer. - * - * @param array $event event data - * @return string formatted line to write to the log - */ - public function format($event) - { - $errno = $event['errno'] ; - $errstr = $event['message'] ; - $errfile = $event['errfile'] ; - $errline = $event['errline'] ; - $backtrace = $event['backtrace'] ; - - $strReturned = ''; - $errno = $errno & error_reporting(); - - // problem when using error_reporting with the @ silent fail operator - // it gives an errno 0, and in this case the objective is to NOT display anything on the screen! - // is there any other case where the errno is zero at this point? - if($errno == 0) return ''; - $strReturned .= "\n<div style='word-wrap: break-word; border: 3px solid red; padding:4px; width:70%; background-color:#FFFF96;'><b>"; - switch($errno) - { - case E_ERROR: $strReturned .= "Error"; break; - case E_WARNING: $strReturned .= "Warning"; break; - case E_PARSE: $strReturned .= "Parse Error"; break; - case E_NOTICE: $strReturned .= "Notice"; break; - case E_CORE_ERROR: $strReturned .= "Core Error"; break; - case E_CORE_WARNING: $strReturned .= "Core Warning"; break; - case E_COMPILE_ERROR: $strReturned .= "Compile Error"; break; - case E_COMPILE_WARNING: $strReturned .= "Compile Warning"; break; - case E_USER_ERROR: $strReturned .= "User Error"; break; - case E_USER_WARNING: $strReturned .= "User Warning"; break; - case E_USER_NOTICE: $strReturned .= "User Notice"; break; - case E_STRICT: $strReturned .= "Strict Notice"; break; - case E_RECOVERABLE_ERROR: $strReturned .= "Recoverable Error"; break; - case E_EXCEPTION: $strReturned .= "Exception"; break; - default: $strReturned .= "Unknown error ($errno)"; break; - } - $strReturned .= ":</b> <i>$errstr</i> in <b>$errfile</b> on line <b>$errline</b>\n"; - $strReturned .= "<br><br>Backtrace --><DIV style='font-family:Courier;font-size:10pt'>"; - $strReturned .= str_replace("\n", "<br>\n", $backtrace); - $strReturned .= "</div><br><br>"; - $strReturned .= "\n</pre></div><br>"; - - return parent::format($strReturned); - } -} - - diff --git a/modules/Log/Exception.php b/modules/Log/Exception.php deleted file mode 100644 index 8b37ff6809..0000000000 --- a/modules/Log/Exception.php +++ /dev/null @@ -1,109 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_Log - * @subpackage Piwik_Log_Exception - */ -require_once "Log.php"; - -/** - * Class used to log an exception event. - * Displays the exception with a user friendly error message, suggests to get support from piwik.org - * - * @package Piwik_Log - * @subpackage Piwik_Log_Exception - */ -class Piwik_Log_Exception extends Piwik_Log -{ - const ID = 'logger_exception'; - function __construct() - { - $logToFileFilename = self::ID; - $logToDatabaseTableName = self::ID; - $logToDatabaseColumnMapping = null; - $screenFormatter = new Piwik_Log_Formatter_Exception_ScreenFormatter; - $fileFormatter = new Piwik_Log_Formatter_FileFormatter; - - parent::__construct($logToFileFilename, - $fileFormatter, - $screenFormatter, - $logToDatabaseTableName, - $logToDatabaseColumnMapping ); - } - - function addWriteToScreen() - { - parent::addWriteToScreen(); - $writerScreen = new Zend_Log_Writer_Stream('php://stderr'); - $writerScreen->setFormatter( $this->screenFormatter ); - $this->addWriter($writerScreen); - } - - public function log($exception) - { - - $event = array(); - $event['errno'] = $exception->getCode(); - $event['message'] = $exception->getMessage(); - $event['errfile'] = $exception->getFile(); - $event['errline'] = $exception->getLine(); - $event['backtrace'] = $exception->getTraceAsString(); - - parent::log($event); - } -} - - -/** - * Format an exception event to be displayed on the screen. - * - * @package Piwik_Log - * @subpackage Piwik_Log_Exception - */ -class Piwik_Log_Formatter_Exception_ScreenFormatter extends Piwik_Log_Formatter_ScreenFormatter -{ - /** - * Formats data into a single line to be written by the writer. - * - * @param array $event event data - * @return string formatted line to write to the log - */ - public function format($event) - { - $errno = $event['errno'] ; - $errstr = $event['message'] ; - $errfile = $event['errfile'] ; - $errline = $event['errline'] ; - $backtrace = $event['backtrace'] ; - - $divId = 'div'.$errline.$errno.rand(1,2000); - - $message = "<b>Uncaught exception</b>: '". $errstr."'"; - $message .= "<br><a onclick=\"if(document.getElementById('$divId').style.display=='none') { document.getElementById('$divId').style.display='inline' } else { document.getElementById('$divId').style.display = 'none' }\" href='#'>". - "\nMore information</a>". - "<div style='display:inline' id='$divId'>". - "<br>In <b>$errfile</b> on line <b>$errline</b>". - "<br><small>Backtrace:<br><pre>"; - $message .= str_replace("\n", "<br>", $backtrace); - $message .= "</pre>"; - $message .= "</small></div>"; - - // without javascript it displays the full error message - // but with javascript we hide the DIV and onclick we show it - $message .= "<script>document.getElementById('$divId').style.display='none';</script>"; - - $message .= "<br>You can get help from <a href='misc/redirectToUrl.php?url=http://piwik.org'>Piwik.org</a> (give us the full error message + your PHP and Mysql version)"; - - return parent::format($message); - } -} - - - - - diff --git a/modules/Log/Message.php b/modules/Log/Message.php deleted file mode 100644 index 62d6fa4b1a..0000000000 --- a/modules/Log/Message.php +++ /dev/null @@ -1,76 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_Log - * @subpackage Piwik_Log_Message - */ - -/** - * 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'; - function __construct() - { - $logToFileFilename = self::ID; - $logToDatabaseTableName = self::ID; - $logToDatabaseColumnMapping = null; - $screenFormatter = new Piwik_Log_Formatter_Message_ScreenFormatter; - $fileFormatter = new Piwik_Log_Formatter_FileFormatter; - - parent::__construct($logToFileFilename, - $fileFormatter, - $screenFormatter, - $logToDatabaseTableName, - $logToDatabaseColumnMapping ); - } - - public function log( $message ) - { - $event = array(); - $event['message'] = $message; - - parent::log($event); - } -} - - -/** - * 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 extends Piwik_Log_Formatter_ScreenFormatter -{ - /** - * Formats data into a single line to be written by the writer. - * - * @param array $event event data - * @return string formatted line to write to the log - */ - public function format($event) - { - if(is_array($event['message'])) - { - $message = "<pre>".var_export($event['message'], true)."</pre>"; - } - else - { - $message = $event['message']; - } - - return parent::format($message); - } -} - diff --git a/modules/LogStats.php b/modules/LogStats.php deleted file mode 100644 index 12151a8b06..0000000000 --- a/modules/LogStats.php +++ /dev/null @@ -1,303 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_LogStats - */ - -/** - * Class used by the logging script piwik.php called by the javascript tag. - * Handles the visitor & his/her actions on the website, saves the data in the DB, saves information in the cookie, etc. - * - * To maximise the performance of the logging module, we use different techniques. - * - * On the PHP-only side: - * - minimize the number of external files included. - * Ideally only one (the configuration file) in all the normal cases. - * We load the Loggers only when an error occurs ; this error is logged in the DB/File/etc - * depending on the loggers settings in the configuration file. - * - we may have to include external classes but we try to include only very - * simple code without any dependency, so that we could simply write a script - * that would merge all this simple code into a big piwik.php file. - * - * On the Database-related side: - * - write all the SQL queries without using any DB abstraction layer. - * Of course we carefully filter all input values. - * - minimize the number of SQL queries necessary to complete the algorithm. - * - carefully index the tables used - * - try to have fixed length rows - * - * [ - use a partitionning by date for the tables ] - * - * - handle the timezone settings?? - * - * 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 - * - * - * Configuration options for the statsLogEngine module: - * - use_cookie ; defines if we try to get/set a cookie to help recognize a unique visitor - * - * @package Piwik_LogStats - */ -class Piwik_LogStats -{ - protected $stateValid; - - protected $urlToRedirect; - - /** - * - * @var Piwik_LogStats_Db - */ - static protected $db = null; - - const STATE_NOTHING_TO_NOTICE = 1; - const STATE_TO_REDIRECT_URL = 2; - const STATE_LOGGING_DISABLE = 10; - const STATE_NO_GET_VARIABLE = 11; - - const COOKIE_INDEX_IDVISITOR = 1; - const COOKIE_INDEX_TIMESTAMP_LAST_ACTION = 2; - const COOKIE_INDEX_TIMESTAMP_FIRST_ACTION = 3; - const COOKIE_INDEX_ID_VISIT = 4; - const COOKIE_INDEX_ID_LAST_ACTION = 5; - - public function __construct() - { - $this->stateValid = self::STATE_NOTHING_TO_NOTICE; - } - - static function connectDatabase() - { - if( !is_null(self::$db)) - { - return; - } - - $configDb = Piwik_LogStats_Config::getInstance()->database; - - // we decode the password. Password is html encoded because it's enclosed between " double quotes - $configDb['password'] = htmlspecialchars_decode($configDb['password']); - if(!isset($configDb['port'])) - { - // before 0.2.4 there is no port specified in config file - $configDb['port'] = '3306'; - } - self::$db = new Piwik_LogStats_Db( $configDb['host'], - $configDb['username'], - $configDb['password'], - $configDb['dbname'], - $configDb['port'] ); - self::$db->connect(); - } - - public static function getDb() - { - return self::$db; - } - - static function disconnectDb() - { - if(isset(self::$db)) - { - self::$db->disconnect(); - } - } - - private function initProcess() - { - try{ - $pluginsLogStats = Piwik_LogStats_Config::getInstance()->Plugins_LogStats; - if(is_array($pluginsLogStats) - && count($pluginsLogStats) != 0) - { - Piwik_PluginsManager::getInstance()->doNotLoadAlwaysActivatedPlugins(); - Piwik_PluginsManager::getInstance()->setPluginsToLoad( $pluginsLogStats['Plugins_LogStats'] ); - } - } catch(Exception $e) { - } - - $saveStats = Piwik_LogStats_Config::getInstance()->LogStats['record_statistics']; - - if($saveStats == 0) - { - $this->setState(self::STATE_LOGGING_DISABLE); - } - - if( count($_GET) == 0) - { - $this->setState(self::STATE_NO_GET_VARIABLE); - } - - $downloadVariableName = Piwik_LogStats_Config::getInstance()->LogStats['download_url_var_name']; - $urlDownload = Piwik_Common::getRequestVar( $downloadVariableName, '', 'string'); - - if( !empty($urlDownload) ) - { - if( Piwik_Common::getRequestVar( 'redirect', 1, 'int') == 1) - { - $this->setState( self::STATE_TO_REDIRECT_URL ); - } - $this->setUrlToRedirect ( $urlDownload); - } - - $outlinkVariableName = Piwik_LogStats_Config::getInstance()->LogStats['outlink_url_var_name']; - $urlOutlink = Piwik_Common::getRequestVar( $outlinkVariableName, '', 'string'); - - if( !empty($urlOutlink) ) - { - if( Piwik_Common::getRequestVar( 'redirect', 1, 'int') == 1) - { - $this->setState( self::STATE_TO_REDIRECT_URL ); - } - $this->setUrlToRedirect ( $urlOutlink); - } - } - - private function processVisit() - { - return $this->stateValid !== self::STATE_LOGGING_DISABLE - && $this->stateValid !== self::STATE_NO_GET_VARIABLE; - } - - private function getState() - { - return $this->stateValid; - } - - private function setUrlToRedirect( $url ) - { - $this->urlToRedirect = $url; - } - - private function getUrlToRedirect() - { - return $this->urlToRedirect; - } - - private function setState( $value ) - { - $this->stateValid = $value; - } - - /** - * Returns the LogStats_Visit object. - * This method can be overwritten so that we use a different LogStats_Visit object - * - * @return Piwik_LogStats_Visit - */ - protected function getNewVisitObject() - { - $visit = null; - Piwik_PostEvent('LogStats.getNewVisitObject', $visit); - - if(is_null($visit)) - { - $visit = new Piwik_LogStats_Visit(); - } - elseif(!($visit instanceof Piwik_LogStats_Visit_Interface )) - { - throw new Exception("The Visit object set in the plugin must implement Piwik_LogStats_Visit_Interface"); - } - - $visit->setDb(self::$db); - return $visit; - } - - // main algorithm - // => input : variables filtered - // => action : read cookie, read database, database logging, cookie writing - function main() - { - $this->initProcess(); - - if( $this->processVisit() ) - { - try { - self::connectDatabase(); - $visit = $this->getNewVisitObject(); - $visit->handle(); - } catch (PDOException $e) { - $this->setState(self::STATE_LOGGING_DISABLE); - } - } - $this->endProcess(); - } - - // display the logo or pixel 1*1 GIF - // or a marketing page if no parameters in the url - // or redirect to a url - // or load a URL (rss feed) (transmit the cookie as well) - protected function endProcess() - { - switch($this->getState()) - { - case self::STATE_LOGGING_DISABLE: - printDebug("Logging disabled, display transparent logo"); - $this->outputTransparentGif(); - break; - - case self::STATE_NO_GET_VARIABLE: - printDebug("No get variables => piwik page"); - echo "<a href='index.php'>Piwik</a> is a free open source <a href='http://piwik.org'>web analytics</a> alternative to Google analytics."; - break; - - - case self::STATE_TO_REDIRECT_URL: - $this->sendHeader('Location: ' . $this->getUrlToRedirect()); - break; - - - case self::STATE_NOTHING_TO_NOTICE: - default: - printDebug("Nothing to notice => default behaviour"); - $this->outputTransparentGif(); - break; - } - printDebug("End of the page."); - - if($GLOBALS['DEBUGPIWIK'] === true) - { - Piwik::printSqlProfilingReportLogStats(self::$db); - } - - self::disconnectDb(); - } - - protected function outputTransparentGif() - { - if( !isset($GLOBALS['DEBUGPIWIK']) || !$GLOBALS['DEBUGPIWIK'] ) - { - $trans_gif_64 = "R0lGODlhAQABAJEAAAAAAP///////wAAACH5BAEAAAIALAAAAAABAAEAAAICVAEAOw=="; - header("Content-type: image/gif"); - print(base64_decode($trans_gif_64)); - } - } - - protected function sendHeader($header) - { - header($header); - } -} - -function printDebug( $info = '' ) -{ - if(isset($GLOBALS['DEBUGPIWIK']) && $GLOBALS['DEBUGPIWIK']) - { - if(is_array($info)) - { - print("<PRE>"); - print(var_export($info,true)); - print("</PRE>"); - } - else - { - print($info . "<br>\n"); - } - } -} diff --git a/modules/LogStats/Action.php b/modules/LogStats/Action.php deleted file mode 100644 index ae15594d78..0000000000 --- a/modules/LogStats/Action.php +++ /dev/null @@ -1,242 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_LogStats - */ - -/** - * Interface of the Action object. - * New Action classes can be defined in plugins and used instead of the default one. - * - * @package Piwik_LogStats - */ -interface Piwik_LogStats_Action_Interface { - public function getActionId(); - public function record( $idVisit, $idRefererAction, $timeSpentRefererAction ); -} - -/** - * 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' - * For example you can decide to use the javascript value document.title as an action_name - * - 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" - * - If the name is empty we set it to default_action_name found in global.ini.php - * - Handling UTF8 in the action name - * PLUGIN_IDEA - An action is associated to URLs and link to the URL from the reports (currently actions do not link to the url of the pages) - * PLUGIN_IDEA - An action hit by a visitor is associated to the HTML title of the page that triggered the action and this HTML title is displayed in the interface - * - * - * @package Piwik_LogStats - */ -class Piwik_LogStats_Action implements Piwik_LogStats_Action_Interface -{ - 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 Database object to be used - */ - function __construct( $db ) - { - $this->actionName = Piwik_Common::getRequestVar( 'action_name', '', 'string'); - - $downloadVariableName = Piwik_LogStats_Config::getInstance()->LogStats['download_url_var_name']; - $this->downloadUrl = Piwik_Common::getRequestVar( $downloadVariableName, '', 'string'); - - $outlinkVariableName = Piwik_LogStats_Config::getInstance()->LogStats['outlink_url_var_name']; - $this->outlinkUrl = Piwik_Common::getRequestVar( $outlinkVariableName, '', 'string'); - - $nameVariableName = Piwik_LogStats_Config::getInstance()->LogStats['download_outlink_name_var']; - $this->nameDownloadOutlink = Piwik_Common::getRequestVar( $nameVariableName, '', 'string'); - - $this->url = Piwik_Common::getRequestVar( 'url', '', 'string'); - $this->db = $db; - $this->defaultActionName = Piwik_LogStats_Config::getInstance()->LogStats['default_action_name']; - } - - - /** - * Returns the idaction of the current action name. - * This idaction is used in the visitor logging table to link the visit information - * (entry action, exit action) to the actions. - * This idaction is also used in the table that links the visits and their actions. - * - * 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 that is associated to this action name in the Actions table lookup - */ - function getActionId() - { - $this->loadActionId(); - return $this->idAction; - } - - - /** - * 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) - { - $this->db->query("INSERT INTO ".$this->db->prefixTable('log_link_visit_action') - ." (idvisit, idaction, idaction_ref, time_spent_ref_action) VALUES (?,?,?,?)", - array($idVisit, $this->idAction, $idRefererAction, $timeSpentRefererAction) - ); - } - - /** - * Generates the name of the action from the URL or the specified name. - * Sets the name as $this->finalActionName - * - * @return void - */ - private function generateInfo() - { - $actionName = ''; - if(!empty($this->downloadUrl)) - { - $this->actionType = self::TYPE_DOWNLOAD; - $url = $this->downloadUrl; - //$actionName = $this->nameDownloadOutlink; - $actionName = $url; - } - elseif(!empty($this->outlinkUrl)) - { - $this->actionType = self::TYPE_OUTLINK; - $url = $this->outlinkUrl; - //remove the last '/' character if it's present - if(substr($url,-1) == '/') - { - $url = substr($url,0,-1); - } - $actionName = $this->nameDownloadOutlink; - if( empty($actionName) ) - { - $actionName = $url; - } - } - else - { - $this->actionType = self::TYPE_ACTION; - $url = $this->url; - $actionName = $this->actionName; - } - - // the ActionName wasn't specified - if( empty($actionName) ) - { - $actionName = trim(Piwik_Common::getPathAndQueryFromUrl($url)); - - // in case the $actionName is ending with a slash, - // which means that it is the index page of a category - // we append the defaultActionName - // toto/tata/ becomes toto/tata/index - if(strlen($actionName) > 0 - && $actionName[strlen($actionName)-1] == '/' - ) - { - $actionName.=$this->defaultActionName; - } - } - - /* - * Clean the action name - */ - - // get the delimiter, by default '/' - $actionCategoryDelimiter = Piwik_LogStats_Config::getInstance()->General['action_category_delimiter']; - - // case the name is an URL we dont clean the name the same way - if(Piwik_Common::isLookLikeUrl($actionName)) - { - $actionName = trim($actionName); - } - else - { - // create an array of the categories delimited by the delimiter - $split = explode($actionCategoryDelimiter, $actionName); - - // trim every category - $split = array_map('trim', $split); - - // remove empty categories - $split = array_filter($split); - - // rebuild the name from the array of cleaned categories - $actionName = implode($actionCategoryDelimiter, $split); - } - - // remove the extra bad characters if any (shouldn't be any at this point...) - $actionName = str_replace(array("\n", "\r"), '', $actionName); - - if(empty($actionName)) - { - $actionName = $this->defaultActionName; - } - - $this->finalActionName = $actionName; - } - - /** - * Sets the attribute $idAction based on $finalActionName and $actionType. - * - * @see getActionId() - */ - private function loadActionId() - { - $this->generateInfo(); - - $name = $this->finalActionName; - $type = $this->actionType; - - $idAction = $this->db->fetch(" SELECT idaction - FROM ".$this->db->prefixTable('log_action') - ." WHERE name = ? AND type = ?", - array($name, $type) - ); - - // the action name has not been found, create it - if($idAction === false) - { - $this->db->query("INSERT INTO ". $this->db->prefixTable('log_action'). "( name, type ) - VALUES (?,?)",array($name,$type) ); - $idAction = $this->db->lastInsertId(); - } - else - { - $idAction = $idAction['idaction']; - } - - $this->idAction = $idAction; - } - -} - diff --git a/modules/LogStats/Config.php b/modules/LogStats/Config.php deleted file mode 100644 index c4247c76fb..0000000000 --- a/modules/LogStats/Config.php +++ /dev/null @@ -1,80 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_LogStats - */ - -/** - * Simple class to access the configuration file - * - * This is essentially a simple version of Zend_Config that we wrote - * because of performance reasons. - * The LogStats module can't afford a dependency with the Zend_Framework. - * - * It's using the php.net/parse_ini_file function to parse the configuration files. - * It can be used to access both user config.ini.php and piwik global.ini.php config file. - * - * @package Piwik_LogStats - */ -class Piwik_LogStats_Config -{ - static private $instance = null; - - /** - * Returns singleton - * - * @return Piwik_LogStats_Config - */ - static public function getInstance() - { - if (self::$instance == null) - { - $c = __CLASS__; - self::$instance = new $c(); - } - return self::$instance; - } - - /** - * Contains configuration files values - * - * @var array - */ - public $config = array(); - - private function __construct() - { - $pathIniFileUser = 'config/config.ini.php'; - $pathIniFileGlobal = 'config/global.ini.php'; - $this->configUser = parse_ini_file($pathIniFileUser, true); - $this->configGlobal = parse_ini_file($pathIniFileGlobal, true); - } - - /** - * Magic get methods catching calls to $config->var_name - * Returns the value if found in the - * - * @param string $name - * @return mixed The value requested, usually a string - * @throws exception if the value requested not found in both files - */ - public function __get( $name ) - { - if(isset($this->configUser[$name])) - { - return $this->configUser[$name]; - } - if(isset($this->configGlobal[$name])) - { - return $this->configGlobal[$name]; - } - throw new Exception("The config element $name is not available in the configuration (check the configuration file)."); - } -} - - diff --git a/modules/LogStats/Db.php b/modules/LogStats/Db.php deleted file mode 100644 index a84e3d5875..0000000000 --- a/modules/LogStats/Db.php +++ /dev/null @@ -1,261 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_LogStats - */ - -/** - * Simple database PDO wrapper. - * We can't afford to have a dependency with the Zend_Db module in LogStats. - * We wrote this simple class - * - * @package Piwik_LogStats - */ - -class Piwik_LogStats_Db -{ - private $connection = null; - private $username; - private $password; - - static private $profiling = false; - - protected $queriesProfiling = array(); - - /** - * Builds the DB object - */ - public function __construct( $host, $username, $password, $dbname, $port, $driverName = 'mysql') - { - $this->dsn = $driverName.":dbname=$dbname;host=$host;port=$port"; - $this->username = $username; - $this->password = $password; - } - - - /** - * Returns true if the SQL profiler is enabled - * Only used by the unit test that tests that the profiler is off on a production server - * - * @return bool - */ - static public function isProfilingEnabled() - { - return self::$profiling; - } - - /** - * Enables the SQL 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::printSqlProfilingReportLogStats(); - * to display the SQLProfiling report and see which queries take time, etc. - */ - static public function enableProfiling() - { - self::$profiling = true; - } - - /** - * Disables the SQL profiling logging. - */ - static public function disableProfiling() - { - self::$profiling = false; - } - - /** - * Connects to the DB - * - * @throws Exception if there was an error connecting the DB - */ - public function connect() - { - if(self::$profiling) - { - $timer = $this->initProfiler(); - } - - $this->connection = new PDO($this->dsn, $this->username, $this->password); - $this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - // we may want to setAttribute(PDO::ATTR_TIMEOUT ) to a few seconds (default is 60) in case the DB is locked - // the piwik.php would stay waiting for the database... bad! - // we delete the password from this object "just in case" it could be printed - $this->password = ''; - - if(self::$profiling) - { - $this->recordQueryProfile('connect', $timer); - } - } - - /** - * Disconnects from the Mysql server - * - * @return void - */ - public function disconnect() - { - if(self::$profiling) - { - $this->recordProfiling(); - } - $this->connection = null; - } - - /** - * 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; - if (!isset($prefix)) { - $prefix = Piwik_LogStats_Config::getInstance()->database['tables_prefix']; - } - return $prefix . $suffix; - } - - /** - * Returns an array containing all the rows of a query result, using optional bound parameters. - * - * @param string Query - * @param array Parameters to bind - * @see also query() - * @throws Exception if an exception occured - */ - public function fetchAll( $query, $parameters = array() ) - { - try { - $sth = $this->query( $query, $parameters ); - if($sth === false) - { - return false; - } - return $sth->fetchAll(PDO::FETCH_ASSOC); - } catch (PDOException $e) { - throw new Exception("Error query: ".$e->getMessage()); - } - } - - /** - * Returns the first row of a query result, using optional bound parameters. - * - * @param string Query - * @param array Parameters to bind - * @see also query() - * - * @throws Exception if an exception occured - */ - public function fetch( $query, $parameters = array() ) - { - try { - $sth = $this->query( $query, $parameters ); - if($sth === false) - { - return false; - } - return $sth->fetch(PDO::FETCH_ASSOC); - } catch (PDOException $e) { - throw new Exception("Error query: ".$e->getMessage()); - } - } - - /** - * Executes a query, using optional bound parameters. - * - * @param string Query - * @param array Parameters to bind - * - * @return PDOStatement or false if failed - * @throw Exception if an exception occured - */ - public function query($query, $parameters = array()) - { - if(is_null($this->connection)) - { - return false; - } - try { - if(self::$profiling) - { - $timer = $this->initProfiler(); - } - - $sth = $this->connection->prepare($query); - $sth->execute( $parameters ); - - if(self::$profiling) - { - $this->recordQueryProfile($query, $timer); - } - return $sth; - } catch (PDOException $e) { - throw new Exception("Error query: ".$e->getMessage()); - } - } - - protected function initProfiler() - { - require_once "Timer.php"; - return new Piwik_Timer; - } - - protected function recordQueryProfile( $query, $timer ) - { - if(!isset($this->queriesProfiling[$query])) $this->queriesProfiling[$query] = array('sum_time_ms' => 0, 'count' => 0); - $time = $timer->getTimeMs(2); - $time += $this->queriesProfiling[$query]['sum_time_ms']; - $count = $this->queriesProfiling[$query]['count'] + 1; - $this->queriesProfiling[$query] = array('sum_time_ms' => $time, 'count' => $count); - } - - /** - * Returns the last inserted ID in the DB - * Wrapper of PDO::lastInsertId() - * - * @return int - */ - public function lastInsertId() - { - return $this->connection->lastInsertId(); - } - - /** - * When destroyed, if SQL profiled enabled, logs the SQL profiling information - */ - public function recordProfiling() - { - if(is_null($this->connection)) - { - return; - } - - // turn off the profiler so we don't profile the following queries - self::$profiling = false; - - foreach($this->queriesProfiling as $query => $info) - { - $time = $info['sum_time_ms']; - $count = $info['count']; - - $queryProfiling = "INSERT INTO ".$this->prefixTable('log_profiling')." - (query,count,sum_time_ms) VALUES (?,$count,$time) - ON DUPLICATE KEY - UPDATE count=count+$count,sum_time_ms=sum_time_ms+$time"; - $this->query($queryProfiling,array($query)); - } - - // turn back on profiling - self::$profiling = true; - } -} - - diff --git a/modules/LogStats/Generator.php b/modules/LogStats/Generator.php deleted file mode 100644 index 4700c20617..0000000000 --- a/modules/LogStats/Generator.php +++ /dev/null @@ -1,666 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_LogStats - */ - -/** - * Class used to generate fake visits. - * Useful to test performances, general functional testing, etc. - * - * Objective: - * Generate thousands of visits / actions per visitor using - * a single request to misc/generateVisits.php - * - * Requirements of the visits generator script. Fields that can be edited: - * - url => campaigns - * - newsletter - * - partner - * - campaign CPC - * - referer - * - search engine - * - misc site - * - same website - * - url => multiple directories, page names - * - multiple idsite - * - multiple settings configurations - * - action_name - * - HTML title - * - * - * @package Piwik_LogStats - * @subpackage Piwik_LogStats_Generator - * - * "Le Generator, il est trop Fort!" - * - Random fan - */ - -class Piwik_LogStats_Generator -{ - /** - * GET parameters array of values to be used for the current visit - * - * @var array ('res' => '1024x768', 'urlref' => 'http://google.com/search?q=piwik', ...) - */ - protected $currentget = array(); - - /** - * Array of all the potential values for the visit parameters - * Values of 'resolution', 'urlref', etc. will be randomly read from this array - * - * @var array ( - * 'res' => array('1024x768','800x600'), - * 'urlref' => array('google.com','intel.com','amazon.com'), - * ....) - */ - protected $allget = array(); - - /** - * See @see setMaximumUrlDepth - * - * @var int - */ - protected $maximumUrlDepth = 1; - - /** - * Unix timestamp to use for the generated visitor - * - * @var int Unix timestamp - */ - protected $timestampToUse; - - /** - * See @see disableProfiler() - * The profiler is enabled by default - * - * @var bool - */ - protected $profiling = true; - - /** - * If set to true, this will TRUNCATE the profiling tables at every new generated visit - * @see initProfiler() - * - * @var bool - */ - public $reinitProfilingAtEveryRequest = true; - - /** - * Hostname used to prefix all the generated URLs - * we could make this variable dynamic so that a visitor can make hit on several hosts and - * only the good ones should be kept (feature not yet implemented in piwik) - * - * @var string - */ - public $host = 'http://localhost'; - - /** - * IdSite to generate visits for (@see setIdSite()) - * - * @var int - */ - public $idSite = 1; - - /** - * Overwrite the global GET/POST/COOKIE variables and set the fake ones @see setFakeRequest() - * Reads the configuration file but disables write to this file - * Creates the database object & enable profiling by default (@see disableProfiler()) - * - */ - public function __construct() - { - $_COOKIE = $_GET = $_REQUEST = $_POST = array(); - - // init GET and REQUEST to the empty array - $this->setFakeRequest(); - - require_once "modules/Piwik.php"; - Piwik::createConfigObject('../config/config.ini.php'); - Zend_Registry::get('config')->doWriteFileWhenUpdated = false; - - // setup database - Piwik::createDatabaseObject(); - - Piwik_LogStats_Db::enableProfiling(); - - $this->timestampToUse = time(); - } - - /** - * Sets the depth level of the generated URLs - * value = 1 => path OR path/page1 - * value = 2 => path OR path/pageRand OR path/dir1/pageRand - * - * @param int Depth - */ - public function setMaximumUrlDepth($value) - { - $this->maximumUrlDepth = (int)$value; - } - - /** - * Set the timestamp to use as the starting time for the visitors times - * You have to call this method for every day you want to generate data - * - * @param int Unix timestamp - */ - public function setTimestampToUse($timestamp) - { - $this->timestampToUse = $timestamp; - } - - /** - * Returns the timestamp to be used as the visitor timestamp - * - * @return int Unix timestamp - */ - public function getTimestampToUse() - { - return $this->timestampToUse; - } - - /** - * Set the idsite to generate the visits for - * To be called before init() - * - * @param int idSite - */ - public function setIdSite($idSite) - { - $this->idSite = $idSite; - } - - /** - * Add a value to the GET global array. - * The generator script will then randomly read a value from this array. - * - * For example, $name = 'res' $aValue = '1024x768' - * - * @param string Name of the parameter _GET[$name] - * @param array|mixed Value of the parameter - * @return void - */ - protected function addParam( $name, $aValue) - { - if(is_array($aValue)) - { - $this->allget[$name] = array_merge( $aValue, - (array)@$this->allget[$name]); - } - else - { - $this->allget[$name][] = $aValue; - } - } - - /** - * TRUNCATE all logs related tables to start a fresh logging database. - * Be careful, any data deleted this way is deleted forever - * - * @return void - */ - public function emptyAllLogTables() - { - $db = Zend_Registry::get('db'); - $db->query('TRUNCATE TABLE '.Piwik::prefixTable('log_action')); - $db->query('TRUNCATE TABLE '.Piwik::prefixTable('log_visit')); - $db->query('TRUNCATE TABLE '.Piwik::prefixTable('log_link_visit_action')); - } - - /** - * Call this method to disable the SQL query profiler - */ - public function disableProfiler() - { - $this->profiling = false; - Piwik_LogStats_Db::disableProfiling(); - } - - /** - * This is called at the end of the Generator script. - * Calls the Profiler output if the profiler is enabled. - * - * @return void - */ - public function end() - { - Piwik_LogStats::disconnectDb(); - if($this->profiling) - { - Piwik::printSqlProfilingReportLogStats(); - } - } - - /** - * Init the Generator script: - * - init the SQL profiler - * - init the random generator - * - setup the different possible values for parameters such as 'resolution', - * 'color', 'hour', 'minute', etc. - * - load from DataFiles and setup values for the other parameters such as UserAgent, Referers, AcceptedLanguages, etc. - * @see /misc/generateVisitsData/ - * - * @return void - */ - public function init() - { - Piwik::createLogObject(); - - $this->initProfiler(); - - /* - * Init the random number generator - */ - function make_seed() - { - list($usec, $sec) = explode(' ', microtime()); - return (float) $sec + ((float) $usec * 100000); - } - mt_srand(make_seed()); - - /* - * Sets values for: resolutions, colors, idSite, times - */ - $common = array( - 'res' => array('1289x800','1024x768','800x600','564x644','200x100','50x2000',), - 'col' => array(24,32,16), - 'idsite'=> $this->idSite, - 'h' => range(0,23), - 'm' => range(0,59), - 's' => range(0,59), - ); - - foreach($common as $label => $values) - { - $this->addParam($label,$values); - } - - /* - * Sets values for: outlinks, downloads, campaigns - */ - // we get the name of the Download/outlink variables - $downloadOrOutlink = array( - Piwik_LogStats_Config::getInstance()->LogStats['download_url_var_name'], - Piwik_LogStats_Config::getInstance()->LogStats['outlink_url_var_name'], - ); - // we have a 20% chance to add a download or outlink variable to the URL - $this->addParam('piwik_downloadOrOutlink', $downloadOrOutlink); - $this->addParam('piwik_downloadOrOutlink', array_fill(0,8,'')); - - // we get the variables name for the campaign parameters - $campaigns = array( - Piwik_LogStats_Config::getInstance()->LogStats['campaign_var_name'], - Piwik_LogStats_Config::getInstance()->LogStats['newsletter_var_name'], - Piwik_LogStats_Config::getInstance()->LogStats['partner_var_name'], - ); - // we generate a campaign in the URL in 3/18 % of the generated URls - $this->addParam('piwik_vars_campaign', $campaigns); - $this->addParam('piwik_vars_campaign', array_fill(0,15,'')); - - - /* - * Sets values for: Referers, user agents, accepted languages - */ - // we load some real referers to be used by the generator - $referers = array(); - require_once "misc/generateVisitsData/Referers.php"; - - $this->addParam('urlref',$referers); - - // and we add 2000 empty referers so that some visitors don't come using a referer (direct entry) - $this->addParam('urlref',array_fill(0,2000,'')); - - // load some user agent and accept language - $userAgent = $acceptLanguages = array(); - require_once "misc/generateVisitsData/UserAgent.php"; - require_once "misc/generateVisitsData/AcceptLanguage.php"; - $this->userAgents=$userAgent; - $this->acceptLanguage=$acceptLanguages; - } - - /** - * If the SQL profiler is enabled and if the reinit at every request is set to true, - * then we TRUNCATE the profiling information so that we only profile one visitor at a time - * - * @return void - */ - protected function initProfiler() - { - /* - * Inits the profiler - */ - if($this->profiling) - { - if($this->reinitProfilingAtEveryRequest) - { - $all = Zend_Registry::get('db')->query('TRUNCATE TABLE '.Piwik::prefixTable('log_profiling').'' ); - } - } - } - /** - * Launches the process and generates an exact number of nbVisits - * For each visit, we setup the timestamp to the common timestamp - * Then we generate between 1 and nbActionsMaxPerVisit actions for this visit - * The generated actions will have a growing timestamp so it looks like a real visit - * - * @param int The number of visits to generate - * @param int The maximum number of actions to generate per visit - * - * @return int The number of total actions generated - */ - public function generate( $nbVisits, $nbActionsMaxPerVisit ) - { - $nbActionsTotal = 0; - for($i = 0; $i < $nbVisits; $i++) - { - $nbActions = mt_rand(1, $nbActionsMaxPerVisit); - - Piwik_LogStats_Generator_Visit::setTimestampToUse($this->getTimestampToUse()); - - $this->generateNewVisit(); - for($j = 1; $j <= $nbActions; $j++) - { - $this->generateActionVisit(); - $this->saveVisit(); - } - - $nbActionsTotal += $nbActions; - } - return $nbActionsTotal; - } - - /** - * Generates a new visitor. - * Loads random values for all the necessary parameters (resolution, local time, referers, etc.) from the fake GET array. - * Also generates a random IP. - * - * We change the superglobal values of HTTP_USER_AGENT, HTTP_CLIENT_IP, HTTP_ACCEPT_LANGUAGE to the generated value. - * - * @return void - */ - protected function generateNewVisit() - { - $this->setCurrentRequest( 'urlref' , $this->getRandom('urlref')); - $this->setCurrentRequest( 'idsite', $this->getRandom('idsite')); - $this->setCurrentRequest( 'res' ,$this->getRandom('res')); - $this->setCurrentRequest( 'col' ,$this->getRandom('col')); - $this->setCurrentRequest( 'h' ,$this->getRandom('h')); - $this->setCurrentRequest( 'm' ,$this->getRandom('m')); - $this->setCurrentRequest( 's' ,$this->getRandom('s')); - $this->setCurrentRequest( 'fla' ,$this->getRandom01()); - $this->setCurrentRequest( 'dir' ,$this->getRandom01()); - $this->setCurrentRequest( 'qt' ,$this->getRandom01()); - $this->setCurrentRequest( 'realp' ,$this->getRandom01()); - $this->setCurrentRequest( 'pdf' ,$this->getRandom01()); - $this->setCurrentRequest( 'wma' ,$this->getRandom01()); - $this->setCurrentRequest( 'java' ,$this->getRandom01()); - $this->setCurrentRequest( 'cookie',$this->getRandom01()); - - $_SERVER['HTTP_CLIENT_IP'] = mt_rand(0,255).".".mt_rand(0,255).".".mt_rand(0,255).".".mt_rand(0,255); - $_SERVER['HTTP_USER_AGENT'] = $this->userAgents[mt_rand(0,count($this->userAgents)-1)]; - $_SERVER['HTTP_ACCEPT_LANGUAGE'] = $this->acceptLanguage[mt_rand(0,count($this->acceptLanguage)-1)]; - } - - /** - * Generates a new action for the current visitor. - * We random generate some campaigns, action names, download or outlink clicks, etc. - * We generate a new Referer, that would be read in the case the visit last page is older than 30 minutes. - * - * This function tries to generate actions that use the features of Piwik (campaigns, downloads, outlinks, action_name set in the JS tag, etc.) - * - * @return void - * - */ - protected function generateActionVisit() - { - // we don't keep the previous action values - // reinit them to empty string - $this->setCurrentRequest( Piwik_LogStats_Config::getInstance()->LogStats['download_outlink_name_var'],''); - $this->setCurrentRequest( Piwik_LogStats_Config::getInstance()->LogStats['download_url_var_name'],''); - $this->setCurrentRequest( Piwik_LogStats_Config::getInstance()->LogStats['outlink_url_var_name'],''); - $this->setCurrentRequest( 'action_name', ''); - - // generate new url referer ; case the visitor stays more than 30min - // (when the visit is known this value will simply be ignored) - $this->setCurrentRequest( 'urlref' , $this->getRandom('urlref')); - - // generates the current URL - $url = $this->getRandomUrlFromHost($this->host); - - // we generate a campaign (partner or newsletter or campaign) - $urlVars = $this->getRandom('piwik_vars_campaign'); - - // if we actually generated a campaign - if(!empty($urlVars)) - { - // campaign name - $urlValue = $this->getRandomString(5,3,'lower'); - - // add the parameter to the url - $url .= '?'. $urlVars . '=' . $urlValue; - - // for a campaign of the CPC kind, we sometimes generate a keyword - if($urlVars == Piwik_LogStats_Config::getInstance()->LogStats['campaign_var_name'] - && mt_rand(0,1)==0) - { - $url .= '&'. Piwik_LogStats_Config::getInstance()->LogStats['campaign_keyword_var_name'] - . '=' . $this->getRandomString(6,3,'ALL');; - } - } - else - { - // we generate a download Or Outlink parameter in the GET request so that - // the current action is counted as a download action OR a outlink click action - $GETParamToAdd = $this->getRandom('piwik_downloadOrOutlink'); - if(!empty($GETParamToAdd)) - { - - $possibleDownloadHosts = array('http://piwik.org/',$this->host); - $nameDownload = $this->getRandomUrlFromHost($possibleDownloadHosts[mt_rand(0,1)]); - $extensions = array('.zip','.tar.gz'); - $nameDownload .= $extensions[mt_rand(0,1)]; - $urlValue = $nameDownload; - - // add the parameter to the url - $this->setCurrentRequest( $GETParamToAdd , $urlValue); - - // in 50% we give a special name to the download/outlink - if(mt_rand(0,1)==0) - { - $nameDownload = $this->getRandomString(6,3,'ALL'); - - $this->setCurrentRequest( Piwik_LogStats_Config::getInstance()->LogStats['download_outlink_name_var'] - , $nameDownload); - } - } - - // if we didn't set any campaign NOR any download click - // then we sometimes set a special action name to the current action - elseif(rand(0,2)==1) - { - $this->setCurrentRequest( 'action_name' , $this->getRandomString(1,1)); - } - } - - $this->setCurrentRequest( 'url' ,$url); - - // setup the title of the page - $this->setCurrentRequest( 'title',$this->getRandomString(15,5)); - } - - /** - * Returns a random URL using the $host as the URL host. - * Depth level depends on @see setMaximumUrlDepth() - * - * @param string Hostname of the URL to generate, eg. http://example.com/ - * - * @return string The generated URL - */ - protected function getRandomUrlFromHost( $host ) - { - $url = $host; - - $deep = mt_rand(0,$this->maximumUrlDepth); - for($i=0;$i<$deep;$i++) - { - $name = $this->getRandomString(1,1,'alnum'); - - $url .= '/'.$name; - } - return $url; - } - - /** - * Generates a random string from minLength to maxLength using a specified set of characters - * - * Taken from php.net and then badly hacked by some unknown monkey - * - * @param int (optional) Maximum length of the string to generate - * @param int (optional) Minimum length of the string to generate - * @param string (optional) Characters set to use, 'ALL' or 'lower' or 'upper' or 'numeric' or 'ALPHA' or 'ALNUM' - * - * @return string The generated random string - */ - protected function getRandomString($maxLength = 15, $minLength = 5, $type = 'ALL') - { - $len = mt_rand($minLength, $maxLength); - - // Register the lower case alphabet array - $alpha = array('a', 'd', 'e', 'f', 'g'); - - // Register the upper case alphabet array - $ALPHA = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', - 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'); - - // Register the numeric array - $num = array('1', '2', '3', '8', '9', '0'); - - // Register the strange array - $strange = array('/', '?', '!','"','£','$','%','^','&','*','(',')',' '); - - // Initialize the keyVals array for use in the for loop - $keyVals = array(); - - // Initialize the key array to register each char - $key = array(); - - // Loop through the choices and register - // The choice to keyVals array - switch ($type) - { - case 'lower' : - $keyVals = $alpha; - break; - case 'upper' : - $keyVals = $ALPHA; - break; - case 'numeric' : - $keyVals = $num; - break; - case 'ALPHA' : - $keyVals = array_merge($alpha, $ALPHA); - break; - case 'alnum' : - $keyVals = array_merge($alpha, $num); - break; - case 'ALNUM' : - $keyVals = array_merge($alpha, $ALPHA, $num); - break; - case 'ALL' : - $keyVals = array_merge($alpha, $ALPHA, $num, $strange); - break; - } - - // Loop as many times as specified - // Register each value to the key array - for($i = 0; $i <= $len-1; $i++) - { - $r = mt_rand(0,count($keyVals)-1); - $key[$i] = $keyVals[$r]; - } - - // Glue the key array into a string and return it - return join("", $key); - } - - /** - * Sets the _GET and _REQUEST superglobal to the current generated array of values. - * @see setCurrentRequest() - * This method is called once the current action parameters array has been generated from - * the global parameters array - * - * @return void - */ - protected function setFakeRequest() - { - $_REQUEST = $_GET = $this->currentget; - } - - /** - * Sets a value in the current action request array. - * - * @param string Name of the parameter to set - * @param string Value of the parameter - */ - protected function setCurrentRequest($name,$value) - { - $this->currentget[$name] = $value; - } - - /** - * Returns a value for the given parameter $name read randomly from the global parameter array. - * @see init() - * - * @param string Name of the parameter value to randomly load and return - * @return mixed Random value for the parameter named $name - * @throws Exception if the parameter asked for has never been set - * - */ - protected function getRandom( $name ) - { - if(!isset($this->allget[$name])) - { - throw new exception("You are asking for $name which doesnt exist"); - } - else - { - $index = mt_rand(0,count($this->allget[$name])-1); - $value =$this->allget[$name][$index]; - return $value; - } - } - - /** - * Returns either 0 or 1 - * - * @return int 0 or 1 - */ - protected function getRandom01() - { - return mt_rand(0,1); - } - - /** - * Saves the visit - * - replaces GET and REQUEST by the fake generated request - * - load the LogStats class and call the method to launch the recording - * - * This will save the visit in the database - * - * @return void - */ - protected function saveVisit() - { - $this->setFakeRequest(); - $process = new Piwik_LogStats_Generator_LogStats; - $process->main(); - } - -} -require_once "Generator/LogStats.php"; -require_once "Generator/Visit.php"; diff --git a/modules/LogStats/Generator/LogStats.php b/modules/LogStats/Generator/LogStats.php deleted file mode 100644 index 92a8d29c39..0000000000 --- a/modules/LogStats/Generator/LogStats.php +++ /dev/null @@ -1,58 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id: Generator.php 404 2008-03-23 01:09:59Z matt $ - * - * @package Piwik_LogStats - */ - - -/** - * Fake Piwik_LogStats that: - * - overwrite the sendHeader method so that no headers are sent. - * - doesn't print the 1pixel transparent GIF at the end of the visit process - * - overwrite the logstat_visit object to use so we use our own logstats_visit @see Piwik_LogStats_Generator_Visit - * - * @package Piwik_LogStats - * @subpackage Piwik_LogStats_Generator - */ -class Piwik_LogStats_Generator_LogStats extends Piwik_LogStats -{ - /** - * Does nothing instead of sending headers - * - * @return void - */ - protected function sendHeader($header) - { - } - - /** - * Does nothing instead of displaying a 1x1 transparent pixel GIF - * - * @return void - */ - protected function endProcess() - { - } - - /** - * Returns our 'generator home made' Piwik_LogStats_Generator_Visit object. - * - * @return Piwik_LogStats_Generator_Visit - */ - protected function getNewVisitObject() - { - $visit = new Piwik_LogStats_Generator_Visit(); - $visit->setDb(self::$db); - return $visit; - } - - static function disconnectDb() - { - return; - } -}
\ No newline at end of file diff --git a/modules/LogStats/Generator/Visit.php b/modules/LogStats/Generator/Visit.php deleted file mode 100644 index 01396d126e..0000000000 --- a/modules/LogStats/Generator/Visit.php +++ /dev/null @@ -1,51 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id: Generator.php 404 2008-03-23 01:09:59Z matt $ - * - * @package Piwik_LogStats - */ - - -/** - * Fake Piwik_LogStats_Visit class that overwrite all the Time related method to be able - * to setup a given timestamp for the generated visitor and actions. - * - * - * @package Piwik_LogStats - * @subpackage Piwik_LogStats_Generator - */ -class Piwik_LogStats_Generator_Visit extends Piwik_LogStats_Visit -{ - static protected $timestampToUse; - - static public function setTimestampToUse($time) - { - self::$timestampToUse = $time; - } - protected function getCurrentDate( $format = "Y-m-d") - { - return date($format, $this->getCurrentTimestamp() ); - } - - protected function getCurrentTimestamp() - { - self::$timestampToUse = max(@$this->visitorInfo['visit_last_action_time'],self::$timestampToUse); - self::$timestampToUse += mt_rand(4,1840); - return self::$timestampToUse; - } - - protected function getDatetimeFromTimestamp($timestamp) - { - return date("Y-m-d H:i:s",$timestamp); - } - - protected function updateCookie() - { - @parent::updateCookie(); - } - -} diff --git a/modules/LogStats/Visit.php b/modules/LogStats/Visit.php deleted file mode 100644 index 1fbee29032..0000000000 --- a/modules/LogStats/Visit.php +++ /dev/null @@ -1,837 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_LogStats - */ - - -interface Piwik_LogStats_Visit_Interface { - function handle(); - function setDb($db); -} - -/** - * 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 implements Piwik_LogStats_Visit_Interface -{ - protected $cookieLog = null; - protected $visitorInfo = array(); - protected $userSettingsInformation = null; - protected $db = null; - - function __construct() - { - $idsite = Piwik_Common::getRequestVar('idsite', 0, 'int'); - if($idsite <= 0) - { - throw new Exception("The 'idsite' in the request is invalid."); - } - - $this->idsite = $idsite; - } - - public function setDb($db) - { - $this->db = $db; - } - - /** - * 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 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 - */ - protected function isExcluded() - { - $excluded = 0; - Piwik_PostEvent('LogStats.Visit.isExcluded', $excluded); - if($excluded) - { - printDebug("Visitor excluded."); - return true; - } - - return false; - } - - /** - * Returns the cookie name used for the Piwik LogStats cookie - * @return string - */ - protected function getCookieName() - { - return Piwik_LogStats_Config::getInstance()->LogStats['cookie_name'] . $this->idsite; - } - - - /** - * This methods tries to see if the visitor has visited the website before. - * - * We have to split the visitor into one of the category - * - Known visitor - * - New visitor - * - * A known visitor is a visitor that has already visited the website in the current month. - * We define a known visitor using the algorithm: - * - * 1) Checking if a cookie contains - * // a unique id for the visitor - * - id_visitor - * - * // the timestamp of the last action in the most recent visit - * - timestamp_last_action - * - * // the timestamp of the first action in the most recent visit - * - timestamp_first_action - * - * // the ID of the most recent visit (which could be in the past or the current visit) - * - id_visit - * - * // the ID of the most recent action - * - id_last_action - * - * 2) If the visitor doesn't have a cookie, we try to look for a similar visitor configuration. - * We search for a visitor with the same plugins/OS/Browser/Resolution for today for this website. - */ - protected function recognizeTheVisitor() - { - $this->visitorKnown = false; - - $this->cookieLog = new Piwik_Cookie( $this->getCookieName() ); - /* - * Case the visitor has the piwik cookie. - * We make sure all the data that should saved in the cookie is available. - */ - - if( false !== ($idVisitor = $this->cookieLog->get( Piwik_LogStats::COOKIE_INDEX_IDVISITOR )) ) - { - $timestampLastAction = $this->cookieLog->get( Piwik_LogStats::COOKIE_INDEX_TIMESTAMP_LAST_ACTION ); - $timestampFirstAction = $this->cookieLog->get( Piwik_LogStats::COOKIE_INDEX_TIMESTAMP_FIRST_ACTION ); - $idVisit = $this->cookieLog->get( Piwik_LogStats::COOKIE_INDEX_ID_VISIT ); - $idLastAction = $this->cookieLog->get( Piwik_LogStats::COOKIE_INDEX_ID_LAST_ACTION ); - - if( $timestampLastAction !== false && is_numeric($timestampLastAction) - && $timestampFirstAction !== false && is_numeric($timestampFirstAction) - && $idVisit !== false && is_numeric($idVisit) - && $idLastAction !== false && is_numeric($idLastAction) - ) - { - $this->visitorInfo['visitor_idcookie'] = $idVisitor; - $this->visitorInfo['visit_last_action_time'] = $timestampLastAction; - $this->visitorInfo['visit_first_action_time'] = $timestampFirstAction; - $this->visitorInfo['idvisit'] = $idVisit; - $this->visitorInfo['visit_exit_idaction'] = $idLastAction; - - $this->visitorKnown = true; - - printDebug("The visitor is known because he has the piwik cookie (idcookie = {$this->visitorInfo['visitor_idcookie']}, idvisit = {$this->visitorInfo['idvisit']}, last action = ".date("r", $this->visitorInfo['visit_last_action_time']).") "); - } - } - - /* - * If the visitor doesn't have the piwik cookie, we look for a visitor that has exactly the same configuration - * and that visited the website today. - */ - if( !$this->visitorKnown ) - { - $userInfo = $this->getUserSettingsInformation(); - $md5Config = $userInfo['config_md5config']; - - $visitRow = $this->db->fetch( - " SELECT visitor_idcookie, - UNIX_TIMESTAMP(visit_last_action_time) as visit_last_action_time, - UNIX_TIMESTAMP(visit_first_action_time) as visit_first_action_time, - idvisit, - visit_exit_idaction - FROM ".$this->db->prefixTable('log_visit'). - " WHERE visit_server_date = ? - AND idsite = ? - AND config_md5config = ? - ORDER BY visit_last_action_time DESC - LIMIT 1", - array( $this->getCurrentDate(), $this->idsite, $md5Config)); - if($visitRow - && count($visitRow) > 0) - { - $this->visitorInfo['visitor_idcookie'] = $visitRow['visitor_idcookie']; - $this->visitorInfo['visit_last_action_time'] = $visitRow['visit_last_action_time']; - $this->visitorInfo['visit_first_action_time'] = $visitRow['visit_first_action_time']; - $this->visitorInfo['idvisit'] = $visitRow['idvisit']; - $this->visitorInfo['visit_exit_idaction'] = $visitRow['visit_exit_idaction']; - - $this->visitorKnown = true; - - printDebug("The visitor is known because of his userSettings+IP (idcookie = {$visitRow['visitor_idcookie']}, idvisit = {$this->visitorInfo['idvisit']}, last action = ".date("r", $this->visitorInfo['visit_last_action_time']).") "); - } - } - } - - /** - * Gets the UserSettings information and returns them in an array of name => value - * - * @return array - */ - protected function getUserSettingsInformation() - { - // we already called this method before, simply returns the result - if(is_array($this->userSettingsInformation)) - { - return $this->userSettingsInformation; - } - - - $plugin_Flash = Piwik_Common::getRequestVar( 'fla', 0, 'int'); - $plugin_Director = Piwik_Common::getRequestVar( 'dir', 0, 'int'); - $plugin_Quicktime = Piwik_Common::getRequestVar( 'qt', 0, 'int'); - $plugin_RealPlayer = Piwik_Common::getRequestVar( 'realp', 0, 'int'); - $plugin_Pdf = Piwik_Common::getRequestVar( 'pdf', 0, 'int'); - $plugin_WindowsMedia = Piwik_Common::getRequestVar( 'wma', 0, 'int'); - $plugin_Java = Piwik_Common::getRequestVar( 'java', 0, 'int'); - $plugin_Cookie = Piwik_Common::getRequestVar( 'cookie', 0, 'int'); - - $userAgent = Piwik_Common::sanitizeInputValues(@$_SERVER['HTTP_USER_AGENT']); - $aBrowserInfo = Piwik_Common::getBrowserInfo($userAgent); - $browserName = $aBrowserInfo['name']; - $browserVersion = $aBrowserInfo['version']; - - $os = Piwik_Common::getOs($userAgent); - - $resolution = Piwik_Common::getRequestVar('res', 'unknown', 'string'); - $colorDepth = Piwik_Common::getRequestVar('col', 32, 'numeric'); - - - $ip = Piwik_Common::getIp(); - $ip = ip2long($ip); - - $browserLang = substr(Piwik_Common::sanitizeInputValues(@$_SERVER['HTTP_ACCEPT_LANGUAGE']), 0, 20); - if(is_null($browserLang)) - { - $browserLang = ''; - } - - - $configurationHash = $this->getConfigHash( - $os, - $browserName, - $browserVersion, - $resolution, - $colorDepth, - $plugin_Flash, - $plugin_Director, - $plugin_RealPlayer, - $plugin_Pdf, - $plugin_WindowsMedia, - $plugin_Java, - $plugin_Cookie, - $ip, - $browserLang); - - $this->userSettingsInformation = array( - 'config_md5config' => $configurationHash, - 'config_os' => $os, - 'config_browser_name' => $browserName, - 'config_browser_version' => $browserVersion, - 'config_resolution' => $resolution, - 'config_color_depth' => $colorDepth, - 'config_pdf' => $plugin_Pdf, - 'config_flash' => $plugin_Flash, - 'config_java' => $plugin_Java, - 'config_director' => $plugin_Director, - 'config_quicktime' => $plugin_Quicktime, - 'config_realplayer' => $plugin_RealPlayer, - 'config_windowsmedia' => $plugin_WindowsMedia, - 'config_cookie' => $plugin_RealPlayer, - 'location_ip' => $ip, - 'location_browser_lang' => $browserLang, - ); - - return $this->userSettingsInformation; - } - - /** - * Returns true if the last action was done during the last 30 minutes - * @return bool - */ - protected function isLastActionInTheSameVisit() - { - return $this->visitorInfo['visit_last_action_time'] - >= ($this->getCurrentTimestamp() - Piwik_LogStats_Config::getInstance()->LogStats['visit_standard_length']); - } - - /** - * Returns true if the recognizeTheVisitor() method did recognize the visitor - */ - protected function isVisitorKnown() - { - return $this->visitorKnown === true; - } - - /** - * 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. - * - * 2) If the last action is less than 30min ago, then the same visit is going on. - * Because the visit goes on, we can get the time spent during the last action. - * - * NB: - * - In the case of a new visit, then the time spent - * 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() - { - if($this->isExcluded()) - { - return; - } - - $this->recognizeTheVisitor(); - if( $this->isVisitorKnown() - && $this->isLastActionInTheSameVisit()) - { - $this->handleKnownVisit(); - } - else - { - $this->handleNewVisit(); - } - - // we update the cookie with the new visit information - $this->updateCookie(); - } - - /** - * Update the cookie information. - */ - protected function updateCookie() - { - printDebug("We manage the cookie..."); - - // idcookie has been generated in handleNewVisit or we simply propagate the old value - $this->cookieLog->set( Piwik_LogStats::COOKIE_INDEX_IDVISITOR, - $this->visitorInfo['visitor_idcookie'] ); - - // the last action timestamp is the current timestamp - $this->cookieLog->set( Piwik_LogStats::COOKIE_INDEX_TIMESTAMP_LAST_ACTION, - $this->visitorInfo['visit_last_action_time'] ); - - // the first action timestamp is the timestamp of the first action of the current visit - $this->cookieLog->set( Piwik_LogStats::COOKIE_INDEX_TIMESTAMP_FIRST_ACTION, - $this->visitorInfo['visit_first_action_time'] ); - - // the idvisit has been generated by mysql in handleNewVisit or simply propagated here - $this->cookieLog->set( Piwik_LogStats::COOKIE_INDEX_ID_VISIT, - $this->visitorInfo['idvisit'] ); - - // the last action ID is the current exit idaction - $this->cookieLog->set( Piwik_LogStats::COOKIE_INDEX_ID_LAST_ACTION, - $this->visitorInfo['visit_exit_idaction'] ); - - $this->cookieLog->save(); - } - - - /** - * In the case of a known visit, we have to do the following actions: - * - * 1) Insert the new action - * - * 2) Update the visit information - */ - protected function handleKnownVisit() - { - printDebug("Visit known."); - - /** - * Init the action - */ - $action = $this->getActionObject(); - $actionId = $action->getActionId(); - printDebug("idAction = $actionId"); - - $serverTime = $this->getCurrentTimestamp(); - $datetimeServer = $this->getDatetimeFromTimestamp($serverTime); - - $this->db->query("UPDATE ". $this->db->prefixTable('log_visit')." - SET visit_last_action_time = ?, - visit_exit_idaction = ?, - visit_total_actions = visit_total_actions + 1, - visit_total_time = UNIX_TIMESTAMP(visit_last_action_time) - UNIX_TIMESTAMP(visit_first_action_time) - WHERE idvisit = ? - LIMIT 1", - array( $datetimeServer, - $actionId, - $this->visitorInfo['idvisit'] ) - ); - /** - * Save the action - */ - $timespentLastAction = $serverTime - $this->visitorInfo['visit_last_action_time']; - - $action->record( $this->visitorInfo['idvisit'], - $this->visitorInfo['visit_exit_idaction'], - $timespentLastAction - ); - - - /** - * Cookie fields to be updated - */ - $this->visitorInfo['visit_last_action_time'] = $serverTime; - $this->visitorInfo['visit_exit_idaction'] = $actionId; - - - } - - /** - * In the case of a new visit, we have to do the following actions: - * - * 1) Insert the new action - * - * 2) Insert the visit information - */ - protected function handleNewVisit() - { - printDebug("New Visit."); - - /** - * Get the variables from the REQUEST - */ - $localTime = Piwik_Common::getRequestVar( 'h', $this->getCurrentDate("H"), 'numeric') - .':'. Piwik_Common::getRequestVar( 'm', $this->getCurrentDate("i"), 'numeric') - .':'. Piwik_Common::getRequestVar( 's', $this->getCurrentDate("s"), 'numeric'); - - $serverTime = $this->getCurrentTimestamp(); - $serverDate = $this->getCurrentDate(); - - if($this->isVisitorKnown()) - { - $idcookie = $this->visitorInfo['visitor_idcookie']; - $returningVisitor = 1; - } - else - { - $idcookie = $this->getVisitorUniqueId(); - $returningVisitor = 0; - } - - $defaultTimeOnePageVisit = Piwik_LogStats_Config::getInstance()->LogStats['default_time_one_page_visit']; - - $userInfo = $this->getUserSettingsInformation(); - $country = Piwik_Common::getCountry($userInfo['location_browser_lang']); - $continent = Piwik_Common::getContinent( $country ); - - $refererInfo = $this->getRefererInformation(); - - /** - * Init the action - */ - $action = $this->getActionObject(); - $actionId = $action->getActionId(); - - printDebug("idAction = $actionId"); - - - /** - * Save the visitor - */ - $informationToSave = array( - 'idsite' => $this->idsite, - 'visitor_localtime' => $localTime, - 'visitor_idcookie' => $idcookie, - 'visitor_returning' => $returningVisitor, - 'visit_first_action_time' => $this->getDatetimeFromTimestamp($serverTime), - 'visit_last_action_time' => $this->getDatetimeFromTimestamp($serverTime), - 'visit_server_date' => $serverDate, - 'visit_entry_idaction' => $actionId, - 'visit_exit_idaction' => $actionId, - 'visit_total_actions' => 1, - 'visit_total_time' => $defaultTimeOnePageVisit, - 'referer_type' => $refererInfo['referer_type'], - 'referer_name' => $refererInfo['referer_name'], - 'referer_url' => $refererInfo['referer_url'], - 'referer_keyword' => $refererInfo['referer_keyword'], - 'config_md5config' => $userInfo['config_md5config'], - 'config_os' => $userInfo['config_os'], - 'config_browser_name' => $userInfo['config_browser_name'], - 'config_browser_version' => $userInfo['config_browser_version'], - 'config_resolution' => $userInfo['config_resolution'], - 'config_color_depth' => $userInfo['config_color_depth'], - 'config_pdf' => $userInfo['config_pdf'], - 'config_flash' => $userInfo['config_flash'], - 'config_java' => $userInfo['config_java'], - 'config_director' => $userInfo['config_director'], - 'config_quicktime' => $userInfo['config_quicktime'], - 'config_realplayer' => $userInfo['config_realplayer'], - 'config_windowsmedia' => $userInfo['config_windowsmedia'], - 'config_cookie' => $userInfo['config_cookie'], - 'location_ip' => $userInfo['location_ip'], - 'location_browser_lang' => $userInfo['location_browser_lang'], - 'location_country' => $country, - 'location_continent' => $continent, - ); - - Piwik_PostEvent('LogStats.newVisitorInformation', $informationToSave); - - $fields = implode(", ", array_keys($informationToSave)); - $values = substr(str_repeat( "?,",count($informationToSave)),0,-1); - - $this->db->query( "INSERT INTO ".$this->db->prefixTable('log_visit'). - " ($fields) VALUES ($values)", array_values($informationToSave)); - - $idVisit = $this->db->lastInsertId(); - - // Update the visitor information attribute with this information array - $this->visitorInfo = $informationToSave; - $this->visitorInfo['idvisit'] = $idVisit; - - // we have to save timestamp in the object properties, whereas mysql eats some other datetime format - $this->visitorInfo['visit_first_action_time'] = $serverTime; - $this->visitorInfo['visit_last_action_time'] = $serverTime; - - // saves the action - $action->record( $idVisit, 0, 0 ); - - } - - /** - * Returns an object able to handle the current action - * Plugins can return an override Action that for example, does not record the action in the DB - * - * @return Piwik_LogStats_Action child or fake but with same public interface - */ - protected function getActionObject() - { - $action = null; - Piwik_PostEvent('LogStats.newAction', $action); - - if(is_null($action)) - { - $action = new Piwik_LogStats_Action( $this->db ); - } - elseif(!($action instanceof Piwik_LogStats_Action_Interface)) - { - throw new Exception("The Action object set in the plugin must implement the interface Piwik_LogStats_Action_Interface"); - } - - return $action; - } - - /** - * Returns an array containing the following information: - * - referer_type - * - direct -- absence of referer URL OR referer URL has the same host - * - site -- based on the referer URL - * - search_engine -- based on the referer URL - * - campaign -- based on campaign URL parameter - * - newsletter -- based on newsletter URL parameter - * - partner -- based on partner URL parameter - * - * - referer_name - * - () - * - piwik.net -- site host name - * - google.fr -- search engine host name - * - adwords-search -- campaign name - * - beta-release -- newsletter name - * - my-nice-partner -- partner name - * - * - referer_keyword - * - () - * - () - * - my keyword - * - my paid keyword - * - () - * - () - * - * - referer_url : the same for all the referer types - * - */ - protected function getRefererInformation() - { - // default values for the referer_* fields - $this->typeRefererAnalyzed = Piwik_Common::REFERER_TYPE_DIRECT_ENTRY; - $this->nameRefererAnalyzed = ''; - $this->keywordRefererAnalyzed = ''; - $this->refererHost = ''; - - // get the urls and parse them - $refererUrl = Piwik_Common::getRequestVar( 'urlref', '', 'string'); - $currentUrl = Piwik_Common::getRequestVar( 'url', '', 'string'); - - $this->refererUrlParse = @parse_url($refererUrl); - $this->currentUrlParse = @parse_url($currentUrl); - if(isset($this->refererUrlParse['host'])) - { - $this->refererHost = $this->refererUrlParse['host']; - } - - $refererDetected = false; - if( !empty($this->currentUrlParse['host'])) - { - if( $this->detectRefererNewsletter() - || $this->detectRefererPartner() - || $this->detectRefererCampaign() ) - { - $refererDetected = true; - } - } - - if(!$refererDetected - && !empty($this->refererUrlParse['host']) ) - { - if( $this->detectRefererSearchEngine() - || $this->detectRefererDirectEntry() ) - { - $refererDetected = true; - } - } - - if(!empty($this->refererHost) - && !$refererDetected) - { - $this->typeRefererAnalyzed = Piwik_Common::REFERER_TYPE_WEBSITE; - $this->nameRefererAnalyzed = $this->refererHost; - } - - $refererInformation = array( - 'referer_type' => $this->typeRefererAnalyzed, - 'referer_name' => $this->nameRefererAnalyzed, - 'referer_keyword' => $this->keywordRefererAnalyzed, - 'referer_url' => $refererUrl, - ); - - return $refererInformation; - } - - /* - * Search engine detection - */ - protected function detectRefererSearchEngine() - { - /* - * A referer is a search engine if the URL's host is in the SearchEngines array - * and if we found the keyword in the URL. - * - * For example if someone comes from http://www.google.com/partners.html this will not - * be counted as a search engines, but as a website referer from google.com (because the - * keyword couldn't be found in the URL) - */ - require "modules/DataFiles/SearchEngines.php"; - - if(array_key_exists($this->refererHost, $GLOBALS['Piwik_SearchEngines'])) - { - $searchEngineName = $GLOBALS['Piwik_SearchEngines'][$this->refererHost][0]; - $variableName = $GLOBALS['Piwik_SearchEngines'][$this->refererHost][1]; - - if(isset($this->refererUrlParse['query'])) - { - $query = $this->refererUrlParse['query']; - - if($searchEngineName == 'Google Images') - { - $query = urldecode(trim(strtolower(Piwik_Common::getParameterFromQueryString($query, 'prev')))); - $query = str_replace('&', '&', strstr($query, '?')); - } - - // search for keywords now &vname=keyword - $key = trim(strtolower(Piwik_Common::getParameterFromQueryString($query, $variableName))); - - if(!empty($key) - && function_exists('iconv') - && isset($GLOBALS['Piwik_SearchEngines'][$this->refererHost][2])) - { - $charset = trim($GLOBALS['Piwik_SearchEngines'][$this->refererHost][2]); - - if(!empty($charset)) - { - $key = htmlspecialchars( - @iconv( $charset, - 'utf-8//TRANSLIT', - htmlspecialchars_decode($key, Piwik_Common::HTML_ENCODING_QUOTE_STYLE)) - , Piwik_Common::HTML_ENCODING_QUOTE_STYLE); - } - } - - if(!empty($key)) - { - $this->typeRefererAnalyzed = Piwik_Common::REFERER_TYPE_SEARCH_ENGINE; - $this->nameRefererAnalyzed = $searchEngineName; - $this->keywordRefererAnalyzed = $key; - - return true; - } - } - } - } - - /* - * Newsletter analysis - */ - protected function detectRefererNewsletter() - { - if(isset($this->currentUrlParse['query'])) - { - $newsletterVariableName = Piwik_LogStats_Config::getInstance()->LogStats['newsletter_var_name']; - $newsletterVar = Piwik_Common::getParameterFromQueryString( $this->currentUrlParse['query'], $newsletterVariableName); - - if(!empty($newsletterVar)) - { - $this->typeRefererAnalyzed = Piwik_Common::REFERER_TYPE_NEWSLETTER; - $this->nameRefererAnalyzed = $newsletterVar; - - return true; - } - } - } - - /* - * Partner analysis - */ - protected function detectRefererPartner() - { - if(isset($this->currentUrlParse['query'])) - { - $partnerVariableName = Piwik_LogStats_Config::getInstance()->LogStats['partner_var_name']; - $partnerVar = Piwik_Common::getParameterFromQueryString($this->currentUrlParse['query'], $partnerVariableName); - - if(!empty($partnerVar)) - { - $this->typeRefererAnalyzed = Piwik_Common::REFERER_TYPE_PARTNER; - $this->nameRefererAnalyzed = $partnerVar; - - return true; - } - } - } - - /* - * Campaign analysis - */ - protected function detectRefererCampaign() - { - if(isset($this->currentUrlParse['query'])) - { - $campaignVariableName = Piwik_LogStats_Config::getInstance()->LogStats['campaign_var_name']; - $campaignName = Piwik_Common::getParameterFromQueryString($this->currentUrlParse['query'], $campaignVariableName); - - if( !empty($campaignName)) - { - $campaignKeywordVariableName = Piwik_LogStats_Config::getInstance()->LogStats['campaign_keyword_var_name']; - $campaignKeyword = Piwik_Common::getParameterFromQueryString($this->currentUrlParse['query'], $campaignKeywordVariableName); - - $this->typeRefererAnalyzed = Piwik_Common::REFERER_TYPE_CAMPAIGN; - $this->nameRefererAnalyzed = $campaignName; - - if(!empty($campaignKeyword)) - { - $this->keywordRefererAnalyzed = $campaignKeyword; - } - - return true; - } - } - } - - - /* - * Direct entry (referer host is similar to current host) - * And we have previously tried to detect the newsletter/partner/campaign variables in the URL - * so it can only be a direct access - */ - - protected function detectRefererDirectEntry() - { - if(isset($this->currentUrlParse['host'])) - { - $currentHost = $this->currentUrlParse['host']; - - if($currentHost == $this->refererHost) - { - $this->typeRefererAnalyzed = Piwik_Common::REFERER_TYPE_DIRECT_ENTRY; - return true; - } - } - - } - - /** - * Returns a MD5 of all the configuration settings - * @return string - */ - protected 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 @see Piwik_Common::generateUniqId() - */ - protected function getVisitorUniqueId() - { - if($this->isVisitorKnown()) - { - return -1; - } - else - { - return Piwik_Common::generateUniqId(); - } - } -} diff --git a/modules/LogStats/javascriptTag.tpl b/modules/LogStats/javascriptTag.tpl deleted file mode 100644 index bb24479777..0000000000 --- a/modules/LogStats/javascriptTag.tpl +++ /dev/null @@ -1,18 +0,0 @@ - -<!-- Piwik --> -<a href="http://piwik.org" title="{$hrefTitle}" onclick="window.open(this.href);return(false);"> -<script type="text/javascript"> -var pkBaseURL = (("https:" == document.location.protocol) ? "https://{$piwikUrl}" : "http://{$piwikUrl}"); -document.write(unescape("%3Cscript src='" + pkBaseURL + "piwik.js' type='text/javascript'%3E%3C/script%3E")); -</script> -<script type="text/javascript"> -<!-- - piwik_action_name = {$actionName}; - piwik_idsite = {$idSite}; - piwik_url = pkBaseURL + "piwik.php"; - piwik_log(piwik_action_name, piwik_idsite, piwik_url); -//--> -</script><object> -<noscript><p>{$hrefTitle} <img src="http://{$piwikUrl}piwik.php" style="border:0" alt="piwik"/></p> -</noscript></object></a> -<!-- /Piwik -->
\ No newline at end of file diff --git a/modules/Mail.php b/modules/Mail.php deleted file mode 100644 index db12d4eaf1..0000000000 --- a/modules/Mail.php +++ /dev/null @@ -1,31 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik - */ - -require_once "Zend/Mail.php"; - -/** - * Class for sending mails, for more information see: - * http://framework.zend.com/manual/en/zend.mail.html - * - * @package Piwik - */ -class Piwik_Mail extends Zend_Mail -{ - /** - * Public constructor, default charset utf-8 - * - * @param string $charset - */ - public function __construct($charset = 'utf-8') - { - parent::__construct($charset); - } -} diff --git a/modules/Period.php b/modules/Period.php deleted file mode 100644 index 212317f79c..0000000000 --- a/modules/Period.php +++ /dev/null @@ -1,239 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_Helper - */ - -require_once "Period/Day.php"; -require_once "Period/Range.php"; -/** - * Creating a new Piwik_Period subclass: - * - * 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. - * - * - * @package Piwik_Helper - */ -abstract class Piwik_Period -{ - protected $subperiods = array(); - protected $subperiodsProcessed = false; - protected $label = null; - protected $date = null; - - protected static $unknowPeriodException = "The period '%s' is not supported. Try 'day' or 'week' or 'month' or 'year'"; - - public function __construct( $date ) - { - $this->checkInputDate( $date ); - $this->date = clone $date; - } - - static public function factory($strPeriod, $date) - { - switch ($strPeriod) { - case 'day': - return new Piwik_Period_Day($date); - break; - - case 'week': - require_once "Period/Week.php"; - return new Piwik_Period_Week($date); - break; - - case 'month': - require_once "Period/Month.php"; - return new Piwik_Period_Month($date); - break; - - case 'year': - require_once "Period/Year.php"; - return new Piwik_Period_Year($date); - break; - - default: - throw new Exception(sprintf(self::$unknowPeriodException, $strPeriod)); - break; - } - } - - /** - * Returns the first day of the period - * - * @return Piwik_Date First day of the period - */ - public function getDateStart() - { - if(!$this->subperiodsProcessed) - { - $this->generate(); - } - if(count($this->subperiods) == 0) - { - return $this->getDate(); - } - $periods = $this->getSubperiods(); - $currentPeriod = $periods[0]; - while( $currentPeriod->getNumberOfSubperiods() > 0 ) - { - $periods = $currentPeriod->getSubperiods(); - $currentPeriod = $periods[0]; - } - return $currentPeriod->getDate(); - } - - /** - * Returns the last day of the period ; can be a date in the future - * - * @return Piwik_Date Last day of the period - */ - public function getDateEnd() - { - if(!$this->subperiodsProcessed) - { - $this->generate(); - } - if(count($this->subperiods) == 0) - { - return $this->getDate(); - } - $periods = $this->getSubperiods(); - $currentPeriod = $periods[count($periods)-1]; - while( $currentPeriod->getNumberOfSubperiods() > 0 ) - { - $periods = $currentPeriod->getSubperiods(); - $currentPeriod = $periods[count($periods)-1]; - } - return $currentPeriod->getDate(); - } - - public function getId() - { - return Piwik::$idPeriods[$this->getLabel()]; - } - - public function getLabel() - { - return $this->label; - } - - /** - * - * @return Piwik_Date - */ - protected function getDate() - { - return $this->date; - } - - protected function checkInputDate($date) - { - if( !($date instanceof Piwik_Date)) - { - throw new Exception("The date must be a Piwik_Date object. " . var_export($date,true)); - } - } - - protected function generate() - { - $this->subperiodsProcessed = true; - } - - public function getNumberOfSubperiods() - { - if(!$this->subperiodsProcessed) - { - $this->generate(); - } - return count($this->subperiods); - } - - /** - * Returns Period_Day for a period made of days (week, month), - * Period_Month for a period made of months (year) - * - * @return array - */ - public function getSubperiods() - { - if(!$this->subperiodsProcessed) - { - $this->generate(); - } - return $this->subperiods; - } - - /** - * Add a date to the period. - * - * Protected because it not yet supported to add periods after the initialization - * - * @param Piwik_Date Valid Piwik_Date object - */ - protected function addSubperiod( $date ) - { - $this->subperiods[] = $date; - } - - /** - * A period is finished if all the subperiods are finished - */ - public function isFinished() - { - if(!$this->subperiodsProcessed) - { - $this->generate(); - } - foreach($this->subperiods as $period) - { - if(!$period->isFinished()) - { - return false; - } - } - return true; - } - - public function toString() - { - if(!$this->subperiodsProcessed) - { - $this->generate(); - } - $dateString = array(); - foreach($this->subperiods as $period) - { - $dateString[] = $period->toString(); - } - return $dateString; - } - - public function __toString() - { - return $this->toString(); - } - - public function get( $part= null ) - { - if(!$this->subperiodsProcessed) - { - $this->generate(); - } - return $this->date->get($part); - } - - abstract public function getPrettyString(); -} - - diff --git a/modules/Period/Day.php b/modules/Period/Day.php deleted file mode 100644 index e4597945de..0000000000 --- a/modules/Period/Day.php +++ /dev/null @@ -1,40 +0,0 @@ -<?php - -/** - * - * @package Piwik_Period - */ -class Piwik_Period_Day extends Piwik_Period -{ - protected $label = 'day'; - - public function getPrettyString() - { - $out = $this->getDateStart()->toString() ; - return $out; - } - - public function isFinished() - { - $todayMidnight = Piwik_Date::today(); - if($this->date->isEarlier($todayMidnight)) - { - return true; - } - } - - public function getNumberOfSubperiods() - { - return 0; - } - - public function addSubperiod( $date ) - { - throw new Exception("Adding a subperiod is not supported for Piwik_Period_Day"); - } - - public function toString() - { - return $this->date->toString("Y-m-d"); - } -} diff --git a/modules/Period/Month.php b/modules/Period/Month.php deleted file mode 100644 index 57fd1d25c5..0000000000 --- a/modules/Period/Month.php +++ /dev/null @@ -1,48 +0,0 @@ -<?php -/** - * - * @package Piwik_Period - */ -class Piwik_Period_Month extends Piwik_Period -{ - protected $label = 'month'; - - public function getPrettyString() - { - $out = $this->getDateStart()->toString('Y-m'); - return $out; - } - - protected function generate() - { - if($this->subperiodsProcessed) - { - return; - } - parent::generate(); - - $date = $this->date; - - $startMonth = $date->setDay(1); - $currentDay = clone $startMonth; - while($currentDay->compareMonth($startMonth) == 0) - { - $this->addSubperiod(new Piwik_Period_Day($currentDay)); - $currentDay = $currentDay->addDay(1); - } - } - - public function isFinished() - { - if(!$this->subperiodsProcessed) - { - $this->generate(); - } - // a month is finished - // if current month > month AND current year == year - // OR if current year > year - $year = $this->date->get("Y"); - return ( date("m") > $this->date->get("m") && date("Y") == $year) - || date("Y") > $year; - } -} diff --git a/modules/Period/Range.php b/modules/Period/Range.php deleted file mode 100644 index 03c97d3e23..0000000000 --- a/modules/Period/Range.php +++ /dev/null @@ -1,165 +0,0 @@ -<?php - -/** - * from a starting date to an ending date - * - */ -class Piwik_Period_Range extends Piwik_Period -{ - public function __construct( $strPeriod, $strDate ) - { - $this->strPeriod = $strPeriod; - $this->strDate = $strDate; - $this->defaultEndDate = null; - } - - public function getPrettyString() - { - $out = "From ".$this->getDateStart()->toString() . " to " . $this->getDateEnd()->toString(); - return $out; - } - - /** - * - * @param Piwik_Date $date - * @param int $n - * @return Piwik_Date - */ - protected function removePeriod( $date, $n ) - { - switch($this->strPeriod) - { - case 'day': - $startDate = $date->subDay( $n ); - break; - - case 'week': - $startDate = $date->subDay( $n * 7 ); - break; - - case 'month': - $startDate = $date->subMonth( $n ); - break; - - case 'year': - $startDate = $date->subMonth( 12 * $n ); - break; - - default: - throw new Exception(sprintf(self::$unknowPeriodException, $this->strPeriod)); - break; - } - return $startDate; - } - - protected function getMaxN($lastN) - { - switch($this->strPeriod) - { - case 'day': - $lastN = min( $lastN, 5*365 ); - break; - - case 'week': - $lastN = min( $lastN, 5*52 ); - break; - - case 'month': - $lastN = min( $lastN, 5*12 ); - break; - - case 'year': - $lastN = min( $lastN, 10 ); - break; - } - return $lastN; - } - - public function setDefaultEndDate( Piwik_Date $oDate) - { - $this->defaultEndDate = $oDate; - } - - protected function generate() - { - if($this->subperiodsProcessed) - { - return; - } - parent::generate(); - - if(ereg('(last|previous)([0-9]*)', $this->strDate, $regs)) - { - $lastN = $regs[2]; - - $lastOrPrevious = $regs[1]; - - if(!is_null($this->defaultEndDate)) - { - $defaultEndDate = $this->defaultEndDate; - } - else - { - $defaultEndDate = Piwik_Date::today(); - } - if($lastOrPrevious == 'last') - { - $endDate = $defaultEndDate; - } - elseif($lastOrPrevious == 'previous') - { - $endDate = $this->removePeriod($defaultEndDate, 1); - } - - // last1 means only one result ; last2 means 2 results so we remove only 1 to the days/weeks/etc - $lastN--; - $lastN = abs($lastN); - - $lastN = $this->getMaxN($lastN); - - $startDate = $this->removePeriod($endDate, $lastN); - } - elseif(ereg('([0-9]{4}-[0-9]{1,2}-[0-9]{1,2}),([0-9]{4}-[0-9]{1,2}-[0-9]{1,2})', $this->strDate, $regs)) - { - $strDateStart = $regs[1]; - $strDateEnd = $regs[2]; - - $startDate = Piwik_Date::factory($strDateStart); - $endDate = Piwik_Date::factory($strDateEnd); - } - else - { - throw new Exception("The date '$this->strDate' is not a date range. Should have the following format: 'lastN' or 'previousN' or 'YYYY-MM-DD,YYYY-MM-DD'."); - } - - $endSubperiod = Piwik_Period::factory($this->strPeriod, $endDate); - - $arrayPeriods= array(); - $arrayPeriods[] = $endSubperiod; - while($endDate->isLater($startDate) ) - { - $endDate = $this->removePeriod($endDate, 1); - $subPeriod = Piwik_Period::factory($this->strPeriod, $endDate); - $arrayPeriods[] = $subPeriod ; - } - $arrayPeriods = array_reverse($arrayPeriods); - foreach($arrayPeriods as $period) - { - $this->addSubperiod($period); - } - } - - function toString() - { - if(!$this->subperiodsProcessed) - { - $this->generate(); - } - $range = array(); - foreach($this->subperiods as $element) - { - $range[] = $element->toString(); - } - return $range; - } -}
\ No newline at end of file diff --git a/modules/Period/Week.php b/modules/Period/Week.php deleted file mode 100644 index f24002c878..0000000000 --- a/modules/Period/Week.php +++ /dev/null @@ -1,41 +0,0 @@ -<?php - -/** - * - * @package Piwik_Period - */ -class Piwik_Period_Week extends Piwik_Period -{ - protected $label = 'week'; - - public function getPrettyString() - { - $out = $this->getDateStart()->toString() . " to " . $this->getDateEnd()->toString(); - return $out; - } - - protected function generate() - { - if($this->subperiodsProcessed) - { - return; - } - parent::generate(); - $date = $this->date; - - if( $date->toString('N') > 1) - { - $date = $date->subDay($date->toString('N')-1); - } - - $startWeek = $date; - - $currentDay = clone $startWeek; - while($currentDay->compareWeek($startWeek) == 0) - { - $this->addSubperiod(new Piwik_Period_Day($currentDay) ); - $currentDay = $currentDay->addDay(1); - } - } - -} diff --git a/modules/Period/Year.php b/modules/Period/Year.php deleted file mode 100644 index 5ff4f083a7..0000000000 --- a/modules/Period/Year.php +++ /dev/null @@ -1,49 +0,0 @@ -<?php - -require_once "Period/Month.php"; -/** - * - * @package Piwik_Period - */ -class Piwik_Period_Year extends Piwik_Period -{ - protected $label = 'year'; - - public function getPrettyString() - { - $out = $this->getDateStart()->toString('Y'); - return $out; - } - - protected function generate() - { - if($this->subperiodsProcessed) - { - return; - } - parent::generate(); - - $year = $this->date->get("Y"); - for($i=1; $i<=12; $i++) - { - $this->addSubperiod( new Piwik_Period_Month( - Piwik_Date::factory("$year-$i-01") - ) - ); - } - } - - function toString() - { - if(!$this->subperiodsProcessed) - { - $this->generate(); - } - $stringMonth = array(); - foreach($this->subperiods as $month) - { - $stringMonth[] = $month->get("Y")."-".$month->get("m")."-01"; - } - return $stringMonth; - } -} diff --git a/modules/Piwik.php b/modules/Piwik.php deleted file mode 100755 index c29ae7b88a..0000000000 --- a/modules/Piwik.php +++ /dev/null @@ -1,1034 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik - */ - -require_once "Config.php"; -require_once "Zend/Db.php"; -require_once "Zend/Db/Table.php"; -require_once "Log.php"; -require_once "PluginsManager.php"; -require_once "Translate.php"; - -/** - * Main piwik helper class. - * Contains static functions you can call from the plugins. - * - * @package Piwik - */ -class Piwik -{ - const CLASSES_PREFIX = "Piwik_"; - - public static $idPeriods = array( - 'day' => 1, - 'week' => 2, - 'month' => 3, - 'year' => 4, - ); - - /** - * ending WITHOUT slashs - */ - static public function getPathToPiwikRoot() - { - return realpath( dirname(__FILE__). "/../" ); - } - - /** - * path without trailing slash - */ - static public function createHtAccess( $path ) - { - @file_put_contents($path . "/.htaccess", "Deny from all"); - } - - static public function mkdir( $path, $mode = 0755, $denyAccess = true ) - { - if(!is_dir($path)) - { - $directoryParent = Piwik::realpath(dirname($path)); - if( is_writable($directoryParent) ) - { - mkdir($path, $mode, true); - } - } - - if($denyAccess) - { - Piwik::createHtAccess($path); - } - } - - /** - * Checks if directories are writable and create them if they do not exist. - * - * @param array $directoriesToCheck array of directories to check - if not given default Piwik directories that needs write permission are checked - * @return array direcory name => true|false (is writable) - */ - static public function checkDirectoriesWritable($directoriesToCheck = null) - { - if( $directoriesToCheck == null ) - { - $directoriesToCheck = array( - '/', - '/config', - '/tmp', - '/tmp/templates_c', - '/tmp/cache', - ); - } - - $resultCheck = array(); - foreach($directoriesToCheck as $directoryToCheck) - { - if( !ereg('^'.preg_quote(PIWIK_INCLUDE_PATH), $directoryToCheck) ) - { - $directoryToCheck = PIWIK_INCLUDE_PATH . $directoryToCheck; - } - - if(!file_exists($directoryToCheck)) - { - Piwik::mkdir($directoryToCheck, 0755, false); - } - - $directory = Piwik::realpath($directoryToCheck); - $resultCheck[$directory] = false; - if(is_writable($directoryToCheck)) - { - $resultCheck[$directory] = true; - } - } - return $resultCheck; - } - - static public function realpath($path) - { - if (file_exists($path)) - { - return realpath($path); - } - return $path; - } - - /** - * Returns the Javascript code to be inserted on every page to track - * - * @param int $idSite - * @param string $piwikUrl http://path/to/piwik/directory/ - * @param string $actionName - * @return string - */ - static public function getJavascriptCode($idSite, $piwikUrl, $actionName = "''") - { - $jsTag = file_get_contents( "modules/LogStats/javascriptTag.tpl"); - $jsTag = nl2br(htmlentities($jsTag)); - $piwikUrl = preg_match('/^(http|https):\/\/(.*)$/', $piwikUrl, $matches); - $piwikUrl = $matches[2]; - $jsTag = str_replace('{$actionName}', $actionName, $jsTag); - $jsTag = str_replace('{$idSite}', $idSite, $jsTag); - $jsTag = str_replace('{$piwikUrl}', $piwikUrl, $jsTag); - $jsTag = str_replace('{$hrefTitle}', Piwik::getRandomTitle(), $jsTag); - return $jsTag; - } - - static public function getMemoryLimitValue() - { - if($memory = ini_get('memory_limit')) - { - return substr($memory, 0, strlen($memory) - 1); - } - return false; - } - - static public function setMemoryLimit($minimumMemoryLimit) - { - $currentValue = self::getMemoryLimitValue(); - if( ($currentValue === false - || $currentValue < $minimumMemoryLimit ) - && @ini_set('memory_limit', $minimumMemoryLimit.'M')) - { - return true; - } - return false; - } - - static public function raiseMemoryLimitIfNecessary() - { - $minimumMemoryLimit = Zend_Registry::get('config')->General->minimum_memory_limit; - $memoryLimit = self::getMemoryLimitValue(); - if($memoryLimit === false - || $memoryLimit < $minimumMemoryLimit) - { - return self::setMemoryLimit($minimumMemoryLimit); - } - - return false; - } - - static public function log($message = '') - { - Zend_Registry::get('logger_message')->log($message); - Zend_Registry::get('logger_message')->log( "<br>" . PHP_EOL); - } - - - static public function error($message = '') - { - trigger_error($message, E_USER_ERROR); - } - - /** - * Display the message in a nice red font with a nice icon - * ... and dies - */ - static public function exitWithErrorMessage( $message ) - { - $output = "<style>a{color:red;}</style>\n". - "<div style='color:red;font-family:Georgia;font-size:120%'>". - "<p><img src='themes/default/images/error_medium.png' style='vertical-align:middle; float:left;padding:20 20 20 20'>". - $message. - "</p></div>"; - print(Piwik_Log_Formatter_ScreenFormatter::getFormattedString($output)); - exit; - } - - /** - * Computes the division of i1 by i2. If either i1 or i2 are not number, or if i2 has a value of zero - * we return 0 to avoid the division by zero. - * - * @param numeric $i1 - * @param numeric $i2 - * @return numeric The result of the division or zero - */ - static public function secureDiv( $i1, $i2 ) - { - if ( is_numeric($i1) && is_numeric($i2) && floatval($i2) != 0) - { - return $i1 / $i2; - } - return 0; - } - static public function getQueryCount() - { - $profiler = Zend_Registry::get('db')->getProfiler(); - return $profiler->getTotalNumQueries(); - } - static public function getDbElapsedSecs() - { - $profiler = Zend_Registry::get('db')->getProfiler(); - return $profiler->getTotalElapsedSecs(); - } - static public function printQueryCount() - { - $totalTime = self::getDbElapsedSecs(); - $queryCount = self::getQueryCount(); - Piwik::log("Total queries = $queryCount (total sql time = ".round($totalTime,2)."s)"); - } - - static public function printSqlProfilingReportLogStats( $db = null ) - { - function maxSumMsFirst($a,$b) - { - return $a['sum_time_ms'] < $b['sum_time_ms']; - } - - if(is_null($db)) - { - $db = Zend_Registry::get('db'); - $tableName = Piwik::prefixTable('log_profiling'); - } - else - { - $tableName = $db->prefixTable('log_profiling'); - } - $all = $db->fetchAll(' SELECT *, sum_time_ms / count as avg_time_ms - FROM '.$tableName ); - if($all === false) - { - return; - } - usort($all, 'maxSumMsFirst'); - - $infoIndexedByQuery = array(); - foreach($all as $infoQuery) - { - $query = $infoQuery['query']; - $count = $infoQuery['count']; - $sum_time_ms = $infoQuery['sum_time_ms']; - $infoIndexedByQuery[$query] = array('count' => $count, 'sumTimeMs' => $sum_time_ms); - } - Piwik::getSqlProfilingQueryBreakdownOutput($infoIndexedByQuery); - } - - /** - * Outputs SQL Profiling reports - * It is automatically called when enabling the SQL profiling in the config file enable_sql_profiler - * - */ - static function printSqlProfilingReportZend() - { - $profiler = Zend_Registry::get('db')->getProfiler(); - - if(!$profiler->getEnabled()) - { - throw new Exception("To display the profiler you should enable enable_sql_profiler on your config/config.ini.php file"); - } - - $infoIndexedByQuery = array(); - foreach($profiler->getQueryProfiles() as $query) - { - if(isset($infoIndexedByQuery[$query->getQuery()])) - { - $existing = $infoIndexedByQuery[$query->getQuery()]; - } - else - { - $existing = array( 'count' => 0, 'sumTimeMs' => 0); - } - $new = array( 'count' => $existing['count'] + 1, - 'sumTimeMs' => $existing['count'] + $query->getElapsedSecs() * 1000); - $infoIndexedByQuery[$query->getQuery()] = $new; - } - function sortTimeDesc($a,$b) - { - return $a['sumTimeMs'] < $b['sumTimeMs']; - } - uasort( $infoIndexedByQuery, 'sortTimeDesc'); - - Piwik::log('<hr><b>SQL Profiler</b>'); - Piwik::log('<hr><b>Summary</b>'); - $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(); - } - } - $str = 'Executed ' . $queryCount . ' queries in ' . round($totalTime,3) . ' seconds' . "\n"; - $str .= '(Average query length: ' . round($totalTime / $queryCount,3) . ' seconds)' . "\n"; - $str .= '<br>Queries per second: ' . round($queryCount / $totalTime,1) . "\n"; - $str .= '<br>Longest query length: ' . round($longestTime,3) . " seconds (<code>$longestQuery</code>) \n"; - Piwik::log($str); - Piwik::getSqlProfilingQueryBreakdownOutput($infoIndexedByQuery); - } - - static private function getSqlProfilingQueryBreakdownOutput( $infoIndexedByQuery ) - { - Piwik::log('<hr><b>Breakdown by query</b>'); - $output = ''; - foreach($infoIndexedByQuery as $query => $queryInfo) - { - $timeMs = round($queryInfo['sumTimeMs'],1); - $count = $queryInfo['count']; - $avgTimeString = ''; - if($count > 1) - { - $avgTimeMs = $timeMs / $count; - $avgTimeString = " (average = <b>". round($avgTimeMs,1) . "ms</b>)"; - } - $query = str_replace(array("\t","\n","\r\n","\r"), "_toberemoved_", $query); - $query = str_replace('_toberemoved__toberemoved_','',$query); - $query = str_replace('_toberemoved_', ' ',$query); - $output .= "Executed <b>$count</b> time". ($count==1?'':'s') ." in <b>".$timeMs."ms</b> $avgTimeString <pre>\t$query</pre>"; - } - Piwik::log($output); - } - - static public function printTimer() - { - echo Zend_Registry::get('timer'); - } - - static public function printMemoryUsage( $prefixString = null ) - { - $memory = false; - if(function_exists('xdebug_memory_usage')) - { - $memory = xdebug_memory_usage(); - } - elseif(function_exists('memory_get_usage')) - { - $memory = memory_get_usage(); - } - - if($memory !== false) - { - $usage = round( $memory / 1024 / 1024, 2); - if(!is_null($prefixString)) - { - Piwik::log($prefixString); - } - Piwik::log("Memory usage = $usage Mb"); - } - else - { - Piwik::log("Memory usage function not found."); - } - } - - static public function isPhpCliMode() - { - return in_array(substr(php_sapi_name(), 0, 3), array('cgi', 'cli')); - } - - static public function isNumeric($value) - { - return !is_array($value) && ereg('^([-]{0,1}[0-9]{1,}[.]{0,1}[0-9]*)$', $value); - } - - static public function getRandomTitle() - { - $titles = array( 'Web analytics', - 'Website analytics', - 'Analytics', - 'Web analytics api', - 'Open source analytics', - 'Open source web analytics', - 'Free analytics', - 'Analytics software', - 'Free web analytics', - 'Free web statistics', - 'Web 2.0 analytics', - 'Web analytic', - 'Web statistics', - 'Web stats', - 'Web 2.0 stats', - 'Statistics web 2.0', - ); - $id = abs(intval(md5(substr(Piwik_Url::getCurrentHost(),7)))); - $title = $titles[ $id % count($titles)]; - return $title; - } - - static public function loadPlugins() - { - Piwik_PluginsManager::getInstance()->setLanguageToLoad( Piwik_Translate::getInstance()->getLanguageToLoad() ); - Piwik_PluginsManager::getInstance()->setPluginsToLoad( Zend_Registry::get('config')->Plugins->Plugins->toArray() ); - } - - static public function installLoadedPlugins() - { - Piwik_PluginsManager::getInstance()->installLoadedPlugins(); - } - - static public function getTableCreateSql( $tableName ) - { - $tables = Piwik::getTablesCreateSql(); - - if(!isset($tables[$tableName])) - { - throw new Exception("The table '$tableName' SQL creation code couldn't be found."); - } - - return $tables[$tableName]; - } - - static public function getTablesCreateSql() - { - $config = Zend_Registry::get('config'); - $prefixTables = $config->database->tables_prefix; - $tables = array( - 'user' => "CREATE TABLE {$prefixTables}user ( - login VARCHAR(20) NOT NULL, - password CHAR(32) NOT NULL, - alias VARCHAR(45) NOT NULL, - email VARCHAR(100) NOT NULL, - token_auth CHAR(32) NOT NULL, - date_registered TIMESTAMP NOT NULL, - PRIMARY KEY(login), - UNIQUE INDEX uniq_keytoken(token_auth) - ) - ", - - 'access' => "CREATE TABLE {$prefixTables}access ( - login VARCHAR(20) NOT NULL, - idsite INTEGER UNSIGNED NOT NULL, - access VARCHAR(10) NULL, - PRIMARY KEY(login, idsite) - ) - ", - - 'site' => "CREATE TABLE {$prefixTables}site ( - idsite INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT, - name VARCHAR(90) NOT NULL, - main_url VARCHAR(255) NOT NULL, - ts_created TIMESTAMP NOT NULL, - PRIMARY KEY(idsite) - ) - ", - - 'site_url' => "CREATE TABLE {$prefixTables}site_url ( - idsite INTEGER(10) UNSIGNED NOT NULL, - url VARCHAR(255) NOT NULL, - PRIMARY KEY(idsite, url) - ) - ", - - - 'logger_message' => "CREATE TABLE {$prefixTables}logger_message ( - idlogger_message INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, - timestamp TIMESTAMP NULL, - message TEXT NULL, - PRIMARY KEY(idlogger_message) - ) - ", - - 'logger_api_call' => "CREATE TABLE {$prefixTables}logger_api_call ( - idlogger_api_call INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, - class_name VARCHAR(255) NULL, - method_name VARCHAR(255) NULL, - parameter_names_default_values TEXT NULL, - parameter_values TEXT NULL, - execution_time FLOAT NULL, - caller_ip BIGINT NULL, - timestamp TIMESTAMP NULL, - returned_value TEXT NULL, - PRIMARY KEY(idlogger_api_call) - ) - ", - - 'logger_error' => "CREATE TABLE {$prefixTables}logger_error ( - idlogger_error INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, - timestamp TIMESTAMP NULL, - message TEXT NULL, - errno INTEGER UNSIGNED NULL, - errline INTEGER UNSIGNED NULL, - errfile VARCHAR(255) NULL, - backtrace TEXT NULL, - PRIMARY KEY(idlogger_error) - ) - ", - - 'logger_exception' => "CREATE TABLE {$prefixTables}logger_exception ( - idlogger_exception INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, - timestamp TIMESTAMP NULL, - message TEXT NULL, - errno INTEGER UNSIGNED NULL, - errline INTEGER UNSIGNED NULL, - errfile VARCHAR(255) NULL, - backtrace TEXT NULL, - PRIMARY KEY(idlogger_exception) - ) - ", - - - 'log_action' => "CREATE TABLE {$prefixTables}log_action ( - idaction INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT, - name VARCHAR(255) NOT NULL, - type TINYINT UNSIGNED NULL, - PRIMARY KEY(idaction) - ) - ", - - 'log_visit' => "CREATE TABLE {$prefixTables}log_visit ( - idvisit INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT, - idsite INTEGER(10) UNSIGNED NOT NULL, - visitor_localtime TIME NOT NULL, - visitor_idcookie CHAR(32) NOT NULL, - visitor_returning TINYINT(1) NOT NULL, - visit_first_action_time DATETIME NOT NULL, - visit_last_action_time DATETIME NOT NULL, - visit_server_date DATE NOT NULL, - visit_exit_idaction INTEGER(11) NOT NULL, - visit_entry_idaction INTEGER(11) NOT NULL, - visit_total_actions SMALLINT(5) UNSIGNED NOT NULL, - visit_total_time SMALLINT(5) UNSIGNED NOT NULL, - referer_type INTEGER UNSIGNED NULL, - referer_name VARCHAR(70) NULL, - referer_url TEXT NOT NULL, - referer_keyword VARCHAR(255) NULL, - config_md5config CHAR(32) NOT NULL, - config_os CHAR(3) NOT NULL, - config_browser_name VARCHAR(10) NOT NULL, - config_browser_version VARCHAR(20) NOT NULL, - config_resolution VARCHAR(9) NOT NULL, - config_color_depth TINYINT(2) UNSIGNED NOT NULL, - config_pdf TINYINT(1) NOT NULL, - config_flash TINYINT(1) NOT NULL, - config_java TINYINT(1) NOT NULL, - config_director TINYINT(1) NOT NULL, - config_quicktime TINYINT(1) NOT NULL, - config_realplayer TINYINT(1) NOT NULL, - config_windowsmedia TINYINT(1) NOT NULL, - config_cookie TINYINT(1) NOT NULL, - location_ip BIGINT(11) NOT NULL, - location_browser_lang VARCHAR(20) NOT NULL, - location_country CHAR(3) NOT NULL, - location_continent CHAR(3) NOT NULL, - PRIMARY KEY(idvisit) - ) - ", - - 'log_link_visit_action' => "CREATE TABLE {$prefixTables}log_link_visit_action ( - idlink_va INTEGER(11) NOT NULL AUTO_INCREMENT, - idvisit INTEGER(10) UNSIGNED NOT NULL, - idaction INTEGER(10) UNSIGNED NOT NULL, - idaction_ref INTEGER(11) UNSIGNED NOT NULL, - time_spent_ref_action INTEGER(10) UNSIGNED NOT NULL, - PRIMARY KEY(idlink_va) - ) - ", - - 'log_profiling' => "CREATE TABLE {$prefixTables}log_profiling ( - query TEXT NOT NULL, - count INTEGER UNSIGNED NULL, - sum_time_ms FLOAT NULL, - UNIQUE INDEX query(query(100)) - ) - ", - - 'archive_numeric' => "CREATE TABLE {$prefixTables}archive_numeric ( - idarchive INTEGER UNSIGNED NOT NULL, - name VARCHAR(255) NOT NULL, - idsite INTEGER UNSIGNED NULL, - date1 DATE NULL, - date2 DATE NULL, - period TINYINT UNSIGNED NULL, - ts_archived DATETIME NULL, - value FLOAT NULL, - PRIMARY KEY(idarchive, name) - ) - ", - 'archive_blob' => "CREATE TABLE {$prefixTables}archive_blob ( - idarchive INTEGER UNSIGNED NOT NULL, - name VARCHAR(255) NOT NULL, - idsite INTEGER UNSIGNED NULL, - date1 DATE NULL, - date2 DATE NULL, - period TINYINT UNSIGNED NULL, - ts_archived DATETIME NULL, - value MEDIUMBLOB NULL, - PRIMARY KEY(idarchive, name) - ) - ", - ); - return $tables; - } - - static public function getCurrentUserLogin() - { - return Zend_Registry::get('access')->getLogin(); - } - - static public function getCurrentUserTokenAuth() - { - return Zend_Registry::get('access')->getTokenAuth(); - } - - static public function isUserIsSuperUserOrTheUser( $theUser ) - { - try{ - self::checkUserIsSuperUserOrTheUser( $theUser ); - return true; - } catch( Exception $e){ - return false; - } - } - - // Accessible either to the user itself - static public function checkUserIsSuperUserOrTheUser( $theUser ) - { - try{ - if( Piwik::getCurrentUserLogin() !== $theUser) - { - // or to the super user - Piwik::checkUserIsSuperUser(); - } - } catch( Piwik_Access_NoAccessException $e){ - throw new Piwik_Access_NoAccessException("The user has to be either the Super User or the user '$theUser' itself."); - } - } - - static public function isUserIsSuperUser() - { - try{ - self::checkUserIsSuperUser(); - return true; - } catch( Exception $e){ - return false; - } - } - - static public function setUserIsSuperUser() - { - Zend_Registry::get('access')->setSuperUser(); - } - - static public function checkUserIsSuperUser() - { - Zend_Registry::get('access')->checkUserIsSuperUser(); - } - - static public function isUserHasAdminAccess( $idSites ) - { - try{ - self::checkUserHasAdminAccess( $idSites ); - return true; - } catch( Exception $e){ - return false; - } - } - - static public function checkUserHasAdminAccess( $idSites ) - { - Zend_Registry::get('access')->checkUserHasAdminAccess( $idSites ); - } - - static public function isUserHasSomeAdminAccess() - { - try{ - self::checkUserHasSomeAdminAccess(); - return true; - } catch( Exception $e){ - return false; - } - } - - static public function checkUserHasSomeAdminAccess() - { - Zend_Registry::get('access')->checkUserHasSomeAdminAccess(); - } - - static public function isUserHasViewAccess( $idSites ) - { - try{ - self::checkUserHasViewAccess( $idSites ); - return true; - } catch( Exception $e){ - return false; - } - } - - static public function checkUserHasViewAccess( $idSites ) - { - Zend_Registry::get('access')->checkUserHasViewAccess( $idSites ); - } - - static public function prefixClass( $class ) - { - if(substr_count($class, Piwik::CLASSES_PREFIX) > 0) - { - return $class; - } - return Piwik::CLASSES_PREFIX.$class; - } - static public function unprefixClass( $class ) - { - $lenPrefix = strlen(Piwik::CLASSES_PREFIX); - if(substr($class, 0, $lenPrefix) == Piwik::CLASSES_PREFIX) - { - return substr($class, $lenPrefix); - } - return $class; - } - - /** - * Returns the current module read from the URL (eg. 'API', 'UserSettings', etc.) - * - * @return string - */ - static public function getModule() - { - return Piwik_Common::getRequestVar('module', '', 'string'); - } - /** - * Returns the current action read from the URL - * - * @return string - */ - static public function getAction() - { - return Piwik_Common::getRequestVar('action', '', 'string'); - } - - /** - * returns false if the URL to redirect to is already this URL - */ - static public function redirectToModule( $newModule, $newAction = '' ) - { - $currentModule = self::getModule(); - $currentAction = self::getAction(); - - if($currentModule != $newModule - || $currentAction != $newAction ) - { - - $newUrl = Piwik_URL::getCurrentUrlWithoutQueryString() - . Piwik_Url::getCurrentQueryStringWithParametersModified( - array('module' => $newModule, 'action' => $newAction) - ); - - Piwik_Url::redirectToUrl($newUrl); - } - return false; - } - - static public function prefixTable( $table ) - { - $config = Zend_Registry::get('config'); - $prefixTables = $config->database->tables_prefix; - return $prefixTables . $table; - } - - /** - * Names of all the prefixed tables in piwik - * Doesn't use the DB - */ - static public function getTablesNames() - { - $aTables = array_keys(self::getTablesCreateSql()); - $config = Zend_Registry::get('config'); - $prefixTables = $config->database->tables_prefix; - $return = array(); - foreach($aTables as $table) - { - $return[] = $prefixTables.$table; - } - return $return; - } - - static $tablesInstalled = null; - - static public function getTablesInstalled( $forceReload = true ) - { - if(is_null(self::$tablesInstalled) - || $forceReload === true) - { - - $db = Zend_Registry::get('db'); - $config = Zend_Registry::get('config'); - $prefixTables = $config->database->tables_prefix; - - $allTables = $db->fetchCol("SHOW TABLES"); - - // all the tables to be installed - $allMyTables = self::getTablesNames(); - - // we get the intersection between all the tables in the DB and the tables to be installed - $tablesInstalled = array_intersect($allMyTables, $allTables); - - // at this point we have only the piwik tables which is good - // but we still miss the piwik generated tables (using the class Piwik_TablePartitioning) - - $allArchiveNumeric = $db->fetchCol("SHOW TABLES LIKE '".$prefixTables."archive_numeric%'"); - $allArchiveBlob = $db->fetchCol("SHOW TABLES LIKE '".$prefixTables."archive_blob%'"); - - $allTablesReallyInstalled = array_merge($tablesInstalled, $allArchiveNumeric, $allArchiveBlob); - - self::$tablesInstalled = $allTablesReallyInstalled; - } - return self::$tablesInstalled; - } - - static public function createDatabase() - { - $db = Zend_Registry::get('db'); - $dbName = Zend_Registry::get('config')->database->dbname; - $db->query("CREATE DATABASE IF NOT EXISTS ".$dbName); - } - - static public function dropDatabase() - { - $db = Zend_Registry::get('db'); - $dbName = Zend_Registry::get('config')->database->dbname; - $db->query("DROP DATABASE IF EXISTS ".$dbName); - } - - - static public function createDatabaseObject( $dbInfos = null ) - { - $config = Zend_Registry::get('config'); - - if(is_null($dbInfos)) - { - $dbInfos = $config->database->toArray(); - } - if(!isset($dbInfos['password'])) - { - $dbInfos['password'] = ''; - } - - // test with the password ='][{}!3456&&^#gegq"eQ for example - if(substr($dbInfos['password'],0,1) == '"' - && substr($dbInfos['password'],-1,1) == '"' - && strlen($dbInfos['password']) >= 2 ) - { - $dbInfos['password'] = substr($dbInfos['password'], 1, -1); - } - $dbInfos['password'] = htmlspecialchars_decode($dbInfos['password']); - - $dbInfos['profiler'] = $config->Debug->enable_sql_profiler; - - $db = Zend_Db::factory($config->database->adapter, $dbInfos); - $db->getConnection(); - // see http://framework.zend.com/issues/browse/ZF-1398 - $db->getConnection()->setAttribute(PDO::ATTR_EMULATE_PREPARES, true); - $db->getConnection()->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true); - Zend_Db_Table::setDefaultAdapter($db); - $db->resetConfigArray(); // we don't want this information to appear in the logs - Zend_Registry::set('db', $db); - } - - static public function createLogObject() - { - require_once "Log/APICall.php"; - require_once "Log/Exception.php"; - require_once "Log/Error.php"; - require_once "Log/Message.php"; - - $configAPI = Zend_Registry::get('config')->log; - - $aLoggers = array( - 'logger_api_call' => new Piwik_Log_APICall, - 'logger_exception' => new Piwik_Log_Exception, - 'logger_error' => new Piwik_Log_Error, - 'logger_message' => new Piwik_Log_Message, - ); - - foreach($configAPI as $loggerType => $aRecordTo) - { - if(isset($aLoggers[$loggerType])) - { - $logger = $aLoggers[$loggerType]; - - foreach($aRecordTo as $recordTo) - { - switch($recordTo) - { - case 'screen': - $logger->addWriteToScreen(); - break; - - case 'database': - $logger->addWriteToDatabase(); - break; - - case 'file': - $logger->addWriteToFile(); - break; - - default: - throw new Exception("TODO"); - break; - } - } - } - } - - foreach($aLoggers as $loggerType =>$logger) - { - if($logger->getWritersCount() == 0) - { - $logger->addWriteToNull(); - } - Zend_Registry::set($loggerType, $logger); - } - } - - - static public function createConfigObject( $pathConfigFile = null ) - { - $config = new Piwik_Config($pathConfigFile); - } - - static public function dropTables( $doNotDelete = array() ) - { - $tablesAlreadyInstalled = self::getTablesInstalled(); - $db = Zend_Registry::get('db'); - - $doNotDeletePattern = "(".implode("|",$doNotDelete).")"; - - foreach($tablesAlreadyInstalled as $tableName) - { - - if( count($doNotDelete) == 0 - || (!in_array($tableName,$doNotDelete) - && !ereg($doNotDeletePattern,$tableName) - ) - ) - { - $db->query("DROP TABLE $tableName"); - } - } - } - - /** - * Returns true if the email is a valid email - * - * @param string email - * @return bool - */ - static public function isValidEmailString( $email ) - { - return (preg_match('/^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9_.-]+\.[a-zA-Z]{2,4}$/', $email) > 0); - } - - /** - * Creates an entry in the User table for the "anonymous" user. - * - * @return void - */ - static public function createAnonymousUser() - { - // The anonymous user is the user that is assigned by default - // note that the token_auth value is anonymous, which is assigned by default as well in the Login plugin - $db = Zend_Registry::get('db'); - $db->query("INSERT INTO ". Piwik::prefixTable("user") . " - VALUES ( 'anonymous', '', 'anonymous', 'anonymous@example.org', 'anonymous', CURRENT_TIMESTAMP );" ); - } - - static public function createTablesIndex() - { - $db = Zend_Registry::get('db'); - $prefixTables = Zend_Registry::get('config')->database->tables_prefix; - - $db->query('CREATE INDEX index_idvisit ON '.$prefixTables.'log_link_visit_action (idvisit)'); - $db->query('CREATE INDEX index_idaction ON '.$prefixTables.'log_action (idaction)'); - $db->query('CREATE INDEX index_idsite ON '.$prefixTables.'log_visit (idsite)'); - $db->query('CREATE INDEX index_visit_server_date ON '.$prefixTables.'log_visit (visit_server_date);'); - } - - static public function createTables() - { - $db = Zend_Registry::get('db'); - $config = Zend_Registry::get('config'); - $prefixTables = $config->database->tables_prefix; - - $tablesAlreadyInstalled = self::getTablesInstalled(); - $tablesToCreate = self::getTablesCreateSql(); - unset($tablesToCreate['archive_blob']); - unset($tablesToCreate['archive_numeric']); - - foreach($tablesToCreate as $tableName => $tableSql) - { - $tableName = $prefixTables . $tableName; - if(!in_array($tableName, $tablesAlreadyInstalled)) - { - $db->query( $tableSql ); - } - } - } - - static public function install() - { - Piwik::mkdir(Zend_Registry::get('config')->smarty->compile_dir); - Piwik::mkdir(Zend_Registry::get('config')->smarty->cache_dir); - } - - static public function uninstall() - { - $db = Zend_Registry::get('db'); - $db->query( "DROP TABLE IF EXISTS ". implode(", ", self::getTablesNames()) ); - } -} - diff --git a/modules/Plugin.php b/modules/Plugin.php deleted file mode 100644 index d0c547f9d3..0000000000 --- a/modules/Plugin.php +++ /dev/null @@ -1,130 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik - */ - - -/** - * 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 -{ - /** - * Returns the plugin details - * 'name' => string // plugin name - * 'description' => string // 1/2 sentences description of the plugin - * 'author' => string // plugin author - * 'author_homepage' => string // author homepage (or email "mailto:youremail@example.org") - * 'homepage' => string // plugin homepage - * 'version' => string // plugin version number - * 'LogStatsPlugin' => bool // should we load this plugin during the stats logging process? - */ - abstract function getInformation(); - - public function registerTranslation( $langCode ) - { - // we are certainly in LogStats mode, Zend is not loaded - if(!class_exists('Zend_Loader')) - { - return ; - } - - $infos = $this->getInformation(); - if(!isset($infos['translationAvailable'])) - { - $infos['translationAvailable'] = false; - } - $translationAvailable = $infos['translationAvailable']; - - if(!$translationAvailable) - { - return; - } - - $name = $infos['name']; - $path = "plugins/" . $name ."/lang/%s.php"; - - $defaultLangPath = sprintf($path, $langCode); - $defaultEnglishLangPath = sprintf($path, 'en'); - - $translations = array(); - - if(Zend_Loader::isReadable($defaultLangPath)) - { - require $defaultLangPath; - } - elseif(Zend_Loader::isReadable($defaultEnglishLangPath)) - { - require $defaultEnglishLangPath; - } - else - { - throw new Exception("Language file not found for the plugin '$name'."); - } - - Piwik_Translate::getInstance()->addTranslationArray($translations); - } - - /** - * Returns the plugin name - */ - public function getName() - { - $info = $this->getInformation(); - return $info['name']; - } - - /** - * Returns the list of hooks registered with the methods names - */ - function getListHooksRegistered() - { - return array(); - } - - /** - * Returns the names of the required plugins - */ - public function getListRequiredPlugins() - { - return array(); - } - - /** - * Executed after loading plugin and registering translations - * Useful for code that uses translated strings from the plugin. - */ - public function postLoad() - { - return; - } - - /** - * Install the plugin - * - create tables - * - update existing tables - * - etc. - */ - public function install() - { - return; - } - - /** - * Remove the created resources during the install - */ - public function uninstall() - { - return; - } -} - diff --git a/modules/PluginsFunctions/AdminMenu.php b/modules/PluginsFunctions/AdminMenu.php deleted file mode 100644 index b450eb04f4..0000000000 --- a/modules/PluginsFunctions/AdminMenu.php +++ /dev/null @@ -1,33 +0,0 @@ -<?php -static $adminMenu = array(); - -function Piwik_GetAdminMenu() -{ - global $adminMenu; - foreach($adminMenu as $key => &$element) - { - if(is_null($element)) - { - unset($adminMenu[$key]); - } - } - return $adminMenu; -} - -function Piwik_AddAdminMenu( $adminMenuName, $url ) -{ - global $adminMenu; - - if(!isset($adminMenu[$adminMenuName])) - { - $adminMenu[$adminMenuName] = $url; - } -} - -function Piwik_RenameAdminMenuEntry($adminMenuOriginal, $adminMenuRenamed) -{ - global $adminMenu; - $save = $adminMenu[$adminMenuOriginal]; - unset($adminMenu[$adminMenuOriginal]); - $adminMenu[$adminMenuRenamed] = $save; -} diff --git a/modules/PluginsFunctions/Menu.php b/modules/PluginsFunctions/Menu.php deleted file mode 100644 index c120b868af..0000000000 --- a/modules/PluginsFunctions/Menu.php +++ /dev/null @@ -1,106 +0,0 @@ -<?php -static $mainMenu = array(); -static $menuEditsToApply = array(); -static $menuRenameToApply = array(); - -// we setup the main categories in a specific order -$mainMenu['Dashboard'] = null; -$mainMenu['General'] = null; -$mainMenu['Visitors'] = null; -$mainMenu['Actions'] = null; -$mainMenu['Referers'] = null; -$mainMenu['Live!'] = null; - - -function Piwik_GetMenu() -{ - global $mainMenu; - global $menuEditsToApply; - global $menuRenameToApply; - - // we apply the list of edits we've registered so far - foreach($menuEditsToApply as $edit) - { - $mainMenuToEdit = $edit[0]; - $subMenuToEdit = $edit[1]; - $newUrl = $edit[2]; - if(!isset($mainMenu[$mainMenuToEdit][$subMenuToEdit])) - { - Piwik_AddMenu($mainMenuToEdit, $subMenuToEdit, $newUrl); - } - else - { - $mainMenu[$mainMenuToEdit][$subMenuToEdit] = $newUrl; - } - } - - // we now apply the menu rename - foreach($menuRenameToApply as $rename) - { - $mainMenuOriginal = $rename[0]; - $subMenuOriginal = $rename[1]; - $mainMenuRenamed = $rename[2]; - $subMenuRenamed = $rename[3]; - if(isset($mainMenu[$mainMenuOriginal][$subMenuOriginal])) - { - $save = $mainMenu[$mainMenuOriginal][$subMenuOriginal]; - unset($mainMenu[$mainMenuOriginal][$subMenuOriginal]); - $mainMenu[$mainMenuRenamed][$subMenuRenamed] = $save; - } - } - - // we now do some cleaning on the menu - foreach($mainMenu as $key => &$element) - { - if(is_null($element)) - { - unset($mainMenu[$key]); - } - else - { - // we want to move some submenus in the first position - $priority = array('Overview','Evolution'); - foreach($priority as $name) - { - if(isset($element[$name])) - { - $newElement = array($name => $element[$name]); - unset($element[$name]); - $element = $newElement + $element; - } - } - $element['_url'] = current($element); - } - } - return $mainMenu; -} - - -function Piwik_AddMenu( $mainMenuName, $subMenuName, $url ) -{ - global $mainMenu; - - if(!isset($mainMenu[$mainMenuName])) - { - $mainMenu[$mainMenuName]['_url'] = $url; - } - if(!empty($subMenuName)) - { - $mainMenu[$mainMenuName][$subMenuName] = $url; - } - -} - -function Piwik_RenameMenuEntry($mainMenuOriginal, $subMenuOriginal, - $mainMenuRenamed, $subMenuRenamed) -{ - global $menuRenameToApply; - $menuRenameToApply[] = array($mainMenuOriginal, $subMenuOriginal, - $mainMenuRenamed, $subMenuRenamed); -} - -function Piwik_EditMenuUrl( $mainMenuToEdit, $subMenuToEdit, $newUrl ) -{ - global $menuEditsToApply; - $menuEditsToApply[] = array($mainMenuToEdit, $subMenuToEdit, $newUrl); -} diff --git a/modules/PluginsFunctions/Sql.php b/modules/PluginsFunctions/Sql.php deleted file mode 100644 index f169c4cf7e..0000000000 --- a/modules/PluginsFunctions/Sql.php +++ /dev/null @@ -1,34 +0,0 @@ -<?php - -/** - * Executes a SQL query on the DB and returns the Zend_Db_Statement object - * If you want to fetch data from the DB you should use the function Piwik_FetchAll() - * - * See also http://framework.zend.com/manual/en/zend.db.statement.html - * - * @param string $sqlQuery - * @param array Parameters to bind in the query, array( param1 => value1, param2 => value2) - * @return Zend_Db_Statement - */ -function Piwik_Query( $sqlQuery, $parameters = array()) -{ - return Zend_Registry::get('db')->query( $sqlQuery, $parameters); -} - -/** - * Executes the SQL Query and fetches all the rows from the database - * - * @param string $sqlQuery - * @param array Parameters to bind in the query, array( param1 => value1, param2 => value2) - * @return array (one row in the array per row fetched in the DB) - */ -function Piwik_FetchAll( $sqlQuery, $parameters = array()) -{ - return Zend_Registry::get('db')->fetchAll( $sqlQuery, $parameters ); -} - -function Piwik_FetchOne( $sqlQuery, $parameters = array()) -{ - return Zend_Registry::get('db')->fetchOne( $sqlQuery, $parameters ); -} - diff --git a/modules/PluginsFunctions/Widget.php b/modules/PluginsFunctions/Widget.php deleted file mode 100644 index 65e90d84fa..0000000000 --- a/modules/PluginsFunctions/Widget.php +++ /dev/null @@ -1,18 +0,0 @@ -<?php - -Piwik_AddAction('Menu', 'Piwik_BuildMenu'); - -static $widgets = array(); - -function Piwik_GetListWidgets() -{ - global $widgets; - return $widgets; -} - -function Piwik_AddWidget( $pluginName, $controllerMethodToCall, $widgetTitle ) -{ - global $widgets; - // get the plugin name from controller - $widgets[$pluginName][] = array( $widgetTitle, $controllerMethodToCall ); -} diff --git a/modules/PluginsManager.php b/modules/PluginsManager.php deleted file mode 100644 index 22ead516e3..0000000000 --- a/modules/PluginsManager.php +++ /dev/null @@ -1,457 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik - */ - - -require_once "Plugin.php"; -require_once "Event/Dispatcher.php"; - -/** - * Plugin specification for a statistics logging plugin - * - * A plugin that display data in the Piwik Interface is very different from a plugin - * that will save additional data in the database during the statistics logging. - * These two types of plugins don't have the same requirements at all. Therefore a plugin - * that saves additional data in the database during the stats logging process will have a different - * structure. - * - * A plugin for logging data has to focus on performance and therefore has to stay as simple as possible. - * For input data, it is strongly advised to use the Piwik methods available in Piwik_Common - * - * Things that can be done with such a plugin: - * - having a dependency with a list of other plugins - * - have an install step that would prepare the plugin environment - * - install could add columns to the tables - * - install could create tables - * - register to hooks at several points in the logging process - * - register to hooks in other plugins - * - generally a plugin method can modify data (filter) and add/remove data - * - * - * @package Piwik - */ -class Piwik_PluginsManager -{ - /** - * Dispatcher - * - * @var Event_Dispatcher - */ - public $dispatcher; - protected $pluginsToLoad = array(); - protected $installPlugins = false; - protected $doLoadPlugins = true; - protected $languageToLoad = null; - protected $loadedPlugins = array(); - - protected $doLoadAlwaysActivatedPlugins = true; - protected $pluginToAlwaysEnable = array( 'CoreHome', - 'CoreAdminHome', - 'CorePluginsAdmin' - ); - - static private $instance = null; - - /** - * Returns the singleton Piwik_PluginsManager - * - * @return Piwik_PluginsManager - */ - static public function getInstance() - { - if (self::$instance == null) - { - $c = __CLASS__; - self::$instance = new $c(); - } - return self::$instance; - } - - private function __construct() - { - $this->dispatcher = Event_Dispatcher::getInstance(); - } - - public function isPluginAlwaysActivated( $name ) - { - return in_array( $name, $this->pluginToAlwaysEnable); - } - public function isPluginEnabled( $name ) - { - return in_array( $name, $this->pluginsToLoad) - || $this->isPluginAlwaysActivated( $name ); - } - - /** - * Reads the directories inside the plugins/ directory and returns their names in an array - * - * @return array - */ - public function readPluginsDirectory() - { - $pluginsName = glob( "plugins/*",GLOB_ONLYDIR); - $pluginsName = array_map('basename', $pluginsName); - return $pluginsName; - } - - public function deactivatePlugin($pluginName) - { - $plugins = $this->pluginsToLoad; - - $key = array_search($pluginName,$plugins); - if($key !== false) - { - unset($plugins[$key]); - Zend_Registry::get('config')->Plugins = $plugins; - } - - try{ - $pluginsLogStats = Zend_Registry::get('config')->Plugins_LogStats->Plugins_LogStats; - if(!is_null($pluginsLogStats)) - { - $pluginsLogStats = $pluginsLogStats->toArray(); - $key = array_search($pluginName,$pluginsLogStats); - if($key !== false) - { - unset($pluginsLogStats[$key]); - Zend_Registry::get('config')->Plugins_LogStats = $pluginsLogStats; - } - } - } catch(Exception $e) {} - } - - /** - * TODO horrible dirty hack because the Config class is not clean enough. Needs to rewrite the Config - * __set and __get in a cleaner way, also see the __destruct which writes the configuration file. - * - * @return array - */ - protected function getInstalledPlugins() - { - if(!class_exists('Zend_Registry')) - { - throw new Exception("Not possible to list installed plugins (case LogStats module)"); - } - if(!is_null(Zend_Registry::get('config')->PluginsInstalled->PluginsInstalled)) - { - return Zend_Registry::get('config')->PluginsInstalled->PluginsInstalled->toArray(); - } - elseif(is_array(Zend_Registry::get('config')->PluginsInstalled)) - { - return Zend_Registry::get('config')->PluginsInstalled; - } - else - { - return Zend_Registry::get('config')->PluginsInstalled->toArray(); - } - } - - public function installLoadedPlugins() - { - foreach($this->getLoadedPlugins() as $plugin) - { - try { - $this->installPluginIfNecessary( $plugin ); - }catch(Exception $e){ - echo $e->getMessage(); - } - } - } - - protected function installPluginIfNecessary( Piwik_Plugin $plugin ) - { - $pluginName = $plugin->getName(); - - // is the plugin already installed or is it the first time we activate it? - $pluginsInstalled = $this->getInstalledPlugins(); - if(!in_array($pluginName,$pluginsInstalled)) - { - $this->installPlugin($plugin); - $pluginsInstalled[] = $pluginName; - Zend_Registry::get('config')->PluginsInstalled = $pluginsInstalled; - } - - $information = $plugin->getInformation(); - - // if the plugin is to be loaded during the statistics logging - if(isset($information['LogStatsPlugin']) - && $information['LogStatsPlugin'] === true) - { - $pluginsLogStats = Zend_Registry::get('config')->Plugins_LogStats->Plugins_LogStats; - if(is_null($pluginsLogStats)) - { - $pluginsLogStats = array(); - } - else - { - $pluginsLogStats = $pluginsLogStats->toArray(); - } - if(!in_array($pluginName, $pluginsLogStats)) - { - $pluginsLogStats[] = $pluginName; - Zend_Registry::get('config')->Plugins_LogStats = $pluginsLogStats; - } - } - } - - public function activatePlugin($pluginName) - { - $plugins = Zend_Registry::get('config')->Plugins->Plugins->toArray(); - if(in_array($pluginName,$plugins)) - { - throw new Exception("Plugin '$pluginName' already activated."); - } - - $existingPlugins = $this->readPluginsDirectory(); - if( array_search($pluginName,$existingPlugins) === false) - { - throw new Exception("Unable to find the plugin '$pluginName'."); - } - - $plugin = $this->loadPlugin($pluginName); - - $this->installPluginIfNecessary($plugin); - - // we add the plugin to the list of activated plugins - $plugins[] = $pluginName; - - // the config file will automatically be saved with the new plugin - Zend_Registry::get('config')->Plugins = $plugins; - } - - public function setPluginsToLoad( array $pluginsToLoad ) - { - // case no plugins to load - if(is_null($pluginsToLoad)) - { - $pluginsToLoad = array(); - } - $this->pluginsToLoad = $pluginsToLoad; - - $this->loadPlugins(); - } - - public function doNotLoadPlugins() - { - $this->doLoadPlugins = false; - } - - public function doNotLoadAlwaysActivatedPlugins() - { - $this->doLoadAlwaysActivatedPlugins = false; - } - /** - * Add a plugin in the loaded plugins array - * - * @param Piwik_Plugin $newPlugin - * @param string plugin name without prefix (eg. 'UserCountry') - */ - protected function addLoadedPlugin( $pluginName, Piwik_Plugin $newPlugin ) - { - $this->loadedPlugins[$pluginName] = $newPlugin; - } - - /** - * Returns an array containing the plugins class names (eg. 'Piwik_UserCountry' and NOT 'UserCountry') - * - * @return array - */ - public function getLoadedPluginsName() - { - $oPlugins = $this->getLoadedPlugins(); - $pluginNames = array_map('get_class',$oPlugins); - return $pluginNames; - } - - /** - * Returns an array of key,value with the following format: array( - * 'UserCountry' => Piwik_Plugin $pluginObject, - * 'UserSettings' => Piwik_Plugin $pluginObject, - * ); - * - * @return array - */ - public function getLoadedPlugins() - { - return $this->loadedPlugins; - } - - /** - * Load the plugins classes installed. - * Register the observers for every plugin. - * - */ - public function loadPlugins() - { - $this->pluginsToLoad = array_unique($this->pluginsToLoad); - - $pluginsToLoad = $this->pluginsToLoad; - - if($this->doLoadAlwaysActivatedPlugins) - { - $pluginsToLoad = array_merge($this->pluginsToLoad, $this->pluginToAlwaysEnable); - } - - foreach($pluginsToLoad as $pluginName) - { - $newPlugin = $this->loadPlugin($pluginName); - - // if we have to load the plugins - // and if this plugin is activated - if($this->doLoadPlugins - && $this->isPluginEnabled($pluginName)) - { - $newPlugin->registerTranslation( $this->languageToLoad ); - $this->addPluginObservers( $newPlugin ); - $this->addLoadedPlugin( $pluginName, $newPlugin); - - $newPlugin->postLoad(); - } - } - } - - /** - * Loads the plugin filename and instanciates the plugin with the given name, eg. UserCountry - * Do NOT give the class name ie. Piwik_UserCountry, but give the plugin name ie. UserCountry - * - * @param Piwik_Plugin $pluginName - */ - public function loadPlugin( $pluginName ) - { - if(isset($this->loadedPlugins[$pluginName])) - { - return $this->loadedPlugins[$pluginName]; - } - $pluginFileName = $pluginName . '/' . $pluginName . ".php"; - $pluginClassName = "Piwik_".$pluginName; - - if( !Piwik_Common::isValidFilename($pluginName)) - { - throw new Exception("The plugin filename '$pluginFileName' is not a valid filename"); - } - - $path = 'plugins/' . $pluginFileName; - - // case LogStats, we don't throw the exception, we don't want to add the Zend overhead - if(class_exists('Zend_Loader') - && !Zend_Loader::isReadable($path)) - { - throw new Exception("<b>The plugin file {$path} couldn't be found. </b><br> - If you are updating from a 0.2.x version, please <a target=_blank href='http://dev.piwik.org/trac/wiki/FAQ#HowdoIupdatefrom0.2.xtothe0.3'>read the FAQ</a>!<br> - Found in your config/config.ini.php file:<br><code>[Plugins]</code><br><code>Plugins[] = $pluginName;</code>"); - } - - require_once $path; - - if(!class_exists($pluginClassName)) - { - throw new Exception("The class $pluginClassName couldn't be found in the file '$path'"); - } - $newPlugin = new $pluginClassName; - - if(!($newPlugin instanceof Piwik_Plugin)) - { - throw new Exception("The plugin $pluginClassName in the file $path must inherit from Piwik_Plugin."); - } - return $newPlugin; - } - - public function installPlugin( Piwik_Plugin $plugin ) - { - try{ - $plugin->install(); - } catch(Exception $e) { - throw new Piwik_Plugin_Exception($plugin->getName(), $e->getMessage()); } - } - - public function installPlugins() - { - foreach($this->getLoadedPlugins() as $plugin) - { - try{ - $plugin->install(); - } catch(Exception $e) { - throw new Piwik_Plugin_Exception($plugin->getName(), $e->getMessage()); - } - } - } - public function setLanguageToLoad( $code ) - { - $this->languageToLoad = $code; - } - - /** - * For the given plugin, add all the observers of this plugin. - */ - private function addPluginObservers( Piwik_Plugin $plugin ) - { - $hooks = $plugin->getListHooksRegistered(); - - foreach($hooks as $hookName => $methodToCall) - { - $this->dispatcher->addObserver( array( $plugin, $methodToCall), $hookName ); - } - } - public function unloadPlugin( $plugin ) - { - if(!($plugin instanceof Piwik_Plugin )) - { - $plugin = $this->loadPlugin( $plugin ); - } - $hooks = $plugin->getListHooksRegistered(); - - foreach($hooks as $hookName => $methodToCall) - { - $success = $this->dispatcher->removeObserver( array( $plugin, $methodToCall), $hookName ); - if($success !== true) - { - throw new Exception("Error unloading plugin for method = $methodToCall // hook = $hookName "); - } - } - unset($this->loadedPlugins[$plugin->getName()]); - } - public function unloadPlugins() - { - $pluginsLoaded = $this->getLoadedPlugins(); - foreach($pluginsLoaded as $plugin) - { - $this->unloadPlugin($plugin); - } - } -} - - -class Piwik_Plugin_Exception extends Exception -{ - function __construct($name, $message) - { - parent::__construct("There was a problem installing the plugin ". $name . " = " . $message. - "<br><b>If this plugin has already been installed, and if you want to hide this message</b>, you must add the following line under the - <code>[PluginsInstalled]</code> entry in your config/config.ini.php file:<br> - <code>PluginsInstalled[] = $name</code><br><br>" ); - } -} - - -/** - * Post an event to the dispatcher which will notice the observers - */ -function Piwik_PostEvent( $eventName, &$object = null, $info = array() ) -{ - Piwik_PluginsManager::getInstance()->dispatcher->post( $object, $eventName, $info, true, false ); -} - -/** - * Register an action to execute for a given event - */ -function Piwik_AddAction( $hookName, $function ) -{ - Piwik_PluginsManager::getInstance()->dispatcher->addObserver( $function, $hookName ); -}
\ No newline at end of file diff --git a/modules/Site.php b/modules/Site.php deleted file mode 100644 index 59d21ad334..0000000000 --- a/modules/Site.php +++ /dev/null @@ -1,67 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_Site - */ - -/** - * - * @package Piwik_Site - */ -class Piwik_Site -{ - protected $id = null; - - protected static $infoSites = array(); - - function __construct($idsite) - { - $this->id = $idsite; - - if(!isset(self::$infoSites[$this->id])) - { - self::$infoSites[$this->id] = Piwik_SitesManager_API::getSiteFromId($idsite); - } - } - function getName() - { - return self::$infoSites[$this->id]['name']; - } - function getMainUrl() - { - return self::$infoSites[$this->id]['main_url']; - } - - function getId() - { - return $this->id; - } - - function getCreationDate() - { - $date = self::$infoSites[$this->id]['ts_created']; - return Piwik_Date::factory($date); - } - - /** - * @param string comma separated idSite list - * @return array of valid integer - */ - static public function getIdSitesFromIdSitesString( $string ) - { - $ids = explode(',', $string); - $validIds = array(); - foreach($ids as $id) - { - $id = trim($id); - $validIds[] = $id; - } - return $validIds; - } -} - diff --git a/modules/SmartyPlugins/function.hiddenurl.php b/modules/SmartyPlugins/function.hiddenurl.php deleted file mode 100644 index c8933aa6c6..0000000000 --- a/modules/SmartyPlugins/function.hiddenurl.php +++ /dev/null @@ -1,46 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id: function.url.php 168 2008-01-14 05:26:43Z matt $ - * - * @package SmartyPlugins - */ - -require_once "Url.php"; - -/** - * Smarty {hiddenurl} function plugin. - * Writes an input Hidden field for every parameter in the URL. - * Useful when using GET forms because we need to print the current parameters - * in hidden input so they are to the next URL after the form is submitted. - * - * - * Examples: - * <pre> - * {hiddenurl module="API"} with a URL 'index.php?action=test&module=CoreHome' will output - * <input type=hidden name=action value=test> - * <input type=hidden name=module value=API> - * </pre> - * - * Set a value to null if you want this value not to be passed in the submitted form. - * - * @param array - * @param Smarty - * @return string - */ -function smarty_function_hiddenurl($params, &$smarty) -{ - $urlModified = Piwik_Url::getCurrentQueryStringWithParametersModified( $params ); - $queryString = htmlspecialchars($urlModified); - $urlValues = Piwik_Common::getArrayFromQueryString($queryString); - - $out = ''; - foreach($urlValues as $name => $value) - { - $out .= '<input type="hidden" name="'.$name.'" value="'.$value.'" />'; - } - return $out; -} diff --git a/modules/SmartyPlugins/function.loadJavascriptTranslations.php b/modules/SmartyPlugins/function.loadJavascriptTranslations.php deleted file mode 100644 index 857147db57..0000000000 --- a/modules/SmartyPlugins/function.loadJavascriptTranslations.php +++ /dev/null @@ -1,61 +0,0 @@ -<?php - -/** - * inserts javascript translation array into the template from given modules - * must be called with 'modules' argument which consists of space-separated module names (i.e. plugins) - * - * - * Example (use in template): - * - * {loadJavascriptTranslations modules='SitesManager CoreHome General'} - * - * loads javascript array translations from main translation file ('General') - * and both 'CoreHome' and 'SitesManager' plugins translations - * - * Note: You can put noHtml=1 option in order to output pure JS code - * - * only translations with '_fs' suffix will be loaded - * - * in order to use translation in your javascript use _pk_translate function - * (it is always loaded with translations): - * - * <script type="text/javascript"> - * alert(_pk_translate('MY_TRANSLATION_STRING')) - * </script> - * - * Note: Use translation string from your translation file WITHOUT '_js' suffix. - * - * _pk_translate DOES NOT support printf() arguments, but you can call: - * - * sprintf(_pk_translate('_NB_OF_EGGS'),'ten') - * (where _NB_OF_EGGS is defined in translation file as i.e. 'There is %s eggs on the table') - * - * sprintf() function is by default included when loading translations - */ - -function smarty_function_loadJavascriptTranslations($params, &$smarty) -{ - if(!isset($params['modules'])) - { - throw new Exception("The smarty function loadJavascriptTranslations needs a 'modules' parameter."); - } - $translate = Piwik_Translate::getInstance(); - $jsTranslations = $translate->getJavascriptTranslations(explode(' ',$params['modules'])); - - $jsCode = ""; - - if( isset($params['noHtml']) ) - { - $jsCode .= "document.write('<scr'+'ipt language=\"javascript\" src=\"libs/javascript/sprintf.js\"><\/scr'+'ipt>');\n"; - $jsCode .= $jsTranslations; - } - else - { - $jsCode .= '<script type="text/javascript" src="libs/javascript/sprintf.js"></script>'; - $jsCode .= '<script type="text/javascript">'; - $jsCode .= $jsTranslations; - $jsCode .= '</script>'; - } - - return $jsCode; -} diff --git a/modules/SmartyPlugins/function.postEvent.php b/modules/SmartyPlugins/function.postEvent.php deleted file mode 100644 index bad7819418..0000000000 --- a/modules/SmartyPlugins/function.postEvent.php +++ /dev/null @@ -1,42 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id: function.url.php 168 2008-01-14 05:26:43Z matt $ - * - * @package SmartyPlugins - */ - -require_once "Url.php"; - -/** - * Posts an event from a smarty template. This event can then be hooked by another plugin. - * The even will be posted along with a string value that plugins can edit. - * This is useful to allow other plugins to add content at a specific entry point in the template. - * This string will be returned by the smarty function. - * - * Examples: - * <pre> - * {postEvent name="template_footerUserCountry"} - * </pre> - * - * Plugins can then hook on this event by using the Piwik_AddAction function: - * Piwik_AddAction('template_footerUserCountry', 'functionToHookOnThisEvent'); - * - * @param string $name The name of the event - * @return string The string eventually modified by the plugins listening to this event - */ -function smarty_function_postEvent($params, &$smarty) -{ - if(!isset($params['name'])) - { - throw new Exception("The smarty function postEvent needs a 'name' parameter."); - } - $eventName = $params['name']; - - $str = ''; - Piwik_PostEvent($eventName, $str); - return $str; -} diff --git a/modules/SmartyPlugins/function.url.php b/modules/SmartyPlugins/function.url.php deleted file mode 100644 index 170002820c..0000000000 --- a/modules/SmartyPlugins/function.url.php +++ /dev/null @@ -1,31 +0,0 @@ -<?php
-/**
- * Piwik - Open source web analytics
- *
- * @link http://piwik.org
- * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later
- * @version $Id$
- *
- * @package SmartyPlugins
- */
-
-require_once "Url.php";
-
-/**
- * Smarty {url} function plugin.
- * Generates a piwik URL with the specified parameters modified.
- *
- * Examples:
- * <pre>
- * {url module="API"} will rewrite the URL modifying the module GET parameter
- * {url module="API" method="getKeywords"} will rewrite the URL modifying the parameters module=API method=getKeywords
- * </pre>
- *
- * @see Piwik_Url::getCurrentQueryStringWithParametersModified()
- * @param $name=$value of the parameters to modify in the generated URL
- * @return string Something like index.php?module=X&action=Y
- */
-function smarty_function_url($params, &$smarty)
-{
- return htmlspecialchars(Piwik_Url::getCurrentScriptName() . Piwik_Url::getCurrentQueryStringWithParametersModified( $params ));
-}
diff --git a/modules/SmartyPlugins/modifier.sumtime.php b/modules/SmartyPlugins/modifier.sumtime.php deleted file mode 100644 index 49a55d69de..0000000000 --- a/modules/SmartyPlugins/modifier.sumtime.php +++ /dev/null @@ -1,54 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package SmartyPlugins - */ - -/** - * Returns a string that displays the number of days and hours from a number of seconds - * - * How to use: - * {4200|sumtime} will display '1h 10min' - * - * Examples: - * - 10 gives "10s" - * - 4200 gives "1h 10min" - * - 86400 gives "1 day" - * - 90600 gives "1 day 1h" (it is exactly 1day 1h 10min but we truncate) - * - * @return string - * - */ -function smarty_modifier_sumtime($string) -{ - $seconds = (double)$string; - $days = floor($seconds / 86400); - - $minusDays = $seconds - $days * 86400; - $hours = floor($minusDays / 3600); - - $minusDaysAndHours = $minusDays - $hours * 3600; - $minutes = floor($minusDaysAndHours / 60 ); - - $minusDaysAndHoursAndMinutes = $minusDaysAndHours - $minutes * 60; - $secondsMod = $minusDaysAndHoursAndMinutes; // should be same as $seconds % 60 - - if($days > 0) - { - return sprintf("%d days %d hours", $days, $hours); - } - elseif($hours > 0) - { - return sprintf("%d hours %d min", $hours, $minutes); - } - else - { - return sprintf("%d min %d s", $minutes, $seconds); - } -} - diff --git a/modules/SmartyPlugins/modifier.translate.php b/modules/SmartyPlugins/modifier.translate.php deleted file mode 100644 index 9942995f66..0000000000 --- a/modules/SmartyPlugins/modifier.translate.php +++ /dev/null @@ -1,34 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id: modifier.sumtime.php 168 2008-01-14 05:26:43Z matt $ - * - * @package SmartyPlugins - */ - -/** - * Read the translation string from the given index (read form the selected language in Piwik). - * The translations strings are located either in /lang/xx.php or within the plugin lang directory. - * - * Example: - * {'General_Unknown'|translate} will be translated as 'Unknown' (see the entry in /lang/en.php) - * - * @return string The translated string - */ -function smarty_modifier_translate($string) -{ - if(func_num_args() <= 1) - { - $aValues = array(); - } - else - { - $aValues = func_get_args(); - array_shift($aValues); - } - return vsprintf(Piwik_Translate($string), $aValues); -} -
\ No newline at end of file diff --git a/modules/SmartyPlugins/modifier.urlRewriteAdminView.php b/modules/SmartyPlugins/modifier.urlRewriteAdminView.php deleted file mode 100644 index d74ad8737b..0000000000 --- a/modules/SmartyPlugins/modifier.urlRewriteAdminView.php +++ /dev/null @@ -1,45 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id: modifier.sumtime.php 168 2008-01-14 05:26:43Z matt $ - * - * @package SmartyPlugins - */ - -/** - * Rewrites the given URL so that it looks like an Admin URL. - * - * @return string - */ -function smarty_modifier_urlRewriteAdminView($parameters) -{ - // replace module=X by moduleToLoad=X - // replace action=Y by actionToLoad=Y - - if( !is_array($parameters) ) { - // if parameters is not an array, parse URL parameteres - $parameters = Piwik_Common::getArrayFromQueryString(htmlspecialchars($parameters)); - } - - $parameters['moduleToLoad'] = $parameters['module']; - unset($parameters['module']); - - if(isset( $parameters['action'])) - { - $parameters['actionToLoad'] = $parameters['action']; - unset($parameters['action']); - } - else - { - $parameters['actionToLoad'] = null; - } - $url = Piwik_Url::getCurrentQueryStringWithParametersModified($parameters); - - // add module=CoreHome&action=showInContext - $url = $url . '&module=CoreAdminHome&action=showInContext'; - return $url; -} - diff --git a/modules/SmartyPlugins/modifier.urlRewriteBasicView.php b/modules/SmartyPlugins/modifier.urlRewriteBasicView.php deleted file mode 100644 index b43aadd479..0000000000 --- a/modules/SmartyPlugins/modifier.urlRewriteBasicView.php +++ /dev/null @@ -1,41 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id: modifier.sumtime.php 168 2008-01-14 05:26:43Z matt $ - * - * @package SmartyPlugins - */ - -/** - * Rewrites the given URL so that it looks like a URL that can be loaded directly. - * Useful for users who don't handle javascript / ajax, they can still use piwik with these rewritten URLs. - * - * @return string - */ -function smarty_modifier_urlRewriteBasicView($parameters) -{ - // replace module=X by moduleToLoad=X - // replace action=Y by actionToLoad=Y - - $parameters['moduleToLoad'] = $parameters['module']; - unset($parameters['module']); - - if(isset( $parameters['action'])) - { - $parameters['actionToLoad'] = $parameters['action']; - unset($parameters['action']); - } - else - { - $parameters['actionToLoad'] = null; - } - $url = Piwik_Url::getCurrentQueryStringWithParametersModified($parameters); - - // add module=CoreHome&action=showInContext - $url = $url . '&module=CoreHome&action=showInContext'; - return htmlspecialchars($url); -} - diff --git a/modules/SmartyPlugins/modifier.urlRewriteWithParameters.php b/modules/SmartyPlugins/modifier.urlRewriteWithParameters.php deleted file mode 100644 index e810b8200f..0000000000 --- a/modules/SmartyPlugins/modifier.urlRewriteWithParameters.php +++ /dev/null @@ -1,23 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id: modifier.sumtime.php 168 2008-01-14 05:26:43Z matt $ - * - * @package SmartyPlugins - */ - -/** - * Rewrites the given URL and modify the given parameters. - * @see Piwik_Url::getCurrentQueryStringWithParametersModified() - * - * @return string - */ -function smarty_modifier_urlRewriteWithParameters($parameters) -{ - $url = Piwik_Url::getCurrentQueryStringWithParametersModified($parameters); - return htmlspecialchars($url); -} - diff --git a/modules/TablePartitioning.php b/modules/TablePartitioning.php deleted file mode 100644 index 3c715518d7..0000000000 --- a/modules/TablePartitioning.php +++ /dev/null @@ -1,132 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik - */ - -/** - * - * NB: When a new table is partitionned using this class, we have to update the method - * Piwik::getTablesInstalled() to add the new table to the list of tablename_* to fetch - * - * @package Piwik - */ -abstract class Piwik_TablePartitioning -{ - protected $tableName = null; - protected $generatedTableName = null; - protected $timestamp = null; - - static public $tablesAlreadyInstalled = null; - - public function __construct( $tableName ) - { - $this->tableName = $tableName; - } - - abstract protected function generateTableName() ; - - - public function setTimestamp( $timestamp ) - { - $this->timestamp = $timestamp; - $this->generatedTableName = null; - $this->getTableName(); - } - - public function getTableName() - { - // table name already processed - if(!is_null($this->generatedTableName)) - { - return $this->generatedTableName; - } - - if(is_null($this->timestamp)) - { - throw new Exception("You have to specify a timestamp for a Table Partitioning by date."); - } - - // generate table name - $this->generatedTableName = $this->generateTableName(); - - // we make sure the table already exists - $this->checkTableExists(); - } - - protected function checkTableExists() - { - if(is_null(self::$tablesAlreadyInstalled)) - { - self::$tablesAlreadyInstalled = Piwik::getTablesInstalled( $forceReload = false ); - } - - if(!in_array($this->generatedTableName, self::$tablesAlreadyInstalled)) - { - $db = Zend_Registry::get('db'); - $sql = Piwik::getTableCreateSql($this->tableName); - - $config = Zend_Registry::get('config'); - $prefixTables = $config->database->tables_prefix; - $sql = str_replace( $prefixTables . $this->tableName, $this->generatedTableName, $sql); - - $db->query( $sql ); - - self::$tablesAlreadyInstalled[] = $this->generatedTableName; - } - } - - protected function __toString() - { - return $this->getTableName(); - } -} - -/** - * - * @package Piwik - */ -class Piwik_TablePartitioning_Monthly extends Piwik_TablePartitioning -{ - public function __construct( $tableName ) - { - parent::__construct($tableName); - } - protected function generateTableName() - { - $config = Zend_Registry::get('config'); - $prefixTables = $config->database->tables_prefix; - - $date = date("Y_m", $this->timestamp); - - return $prefixTables . $this->tableName . "_" . $date; - } - -} -/** - * - * @package Piwik - */ -class Piwik_TablePartitioning_Daily extends Piwik_TablePartitioning -{ - public function __construct( $tableName ) - { - parent::__construct($tableName); - } - protected function generateTableName() - { - $config = Zend_Registry::get('config'); - $prefixTables = $config->database->tables_prefix; - - $date = date("Y_m_d", $this->timestamp); - - return $prefixTables . $this->tableName . "_" . $date; - } - -} - diff --git a/modules/Timer.php b/modules/Timer.php deleted file mode 100644 index 0bbc4bf323..0000000000 --- a/modules/Timer.php +++ /dev/null @@ -1,50 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_Helper - */ - -/** - * - * @package Piwik_Helper - */ -class Piwik_Timer -{ - private $m_Start; - - public function __construct() - { - $this->m_Start = 0.0; - $this->init(); - } - - private function getMicrotime() - { - list($micro_seconds, $seconds) = explode(" ", microtime()); - return ((float)$micro_seconds + (float)$seconds); - } - - public function init() - { - $this->m_Start = $this->getMicrotime(); - } - - public function getTime($decimals = 2) - { - return number_format($this->getMicrotime() - $this->m_Start, $decimals, '.', ''); - } - public function getTimeMs($decimals = 2) - { - return number_format(1000*($this->getMicrotime() - $this->m_Start), $decimals, '.', ''); - } - - public function __toString() - { - return "Time elapsed: ". $this->getTime() ."s"; - } -} diff --git a/modules/Translate.php b/modules/Translate.php deleted file mode 100644 index 82b51c1863..0000000000 --- a/modules/Translate.php +++ /dev/null @@ -1,155 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik - */ - -/** - * @package Piwik - */ -class Piwik_Translate -{ - static private $instance = null; - - /** - * Returns singleton - * - * @return Piwik_Translate - */ - static public function getInstance() - { - if (self::$instance == null) - { - $c = __CLASS__; - self::$instance = new $c(); - } - return self::$instance; - } - - private function __construct() - { - $translations = array(); - - $language = $this->getFallbackLanguageToLoad(); - require_once "lang/" . $language .".php"; - $this->addTranslationArray($translations); - - $language = $this->getLanguageToLoad(); - require_once "lang/" . $language .".php"; - $this->addTranslationArray($translations); - - setlocale(LC_ALL, $GLOBALS['Piwik_translations']['General_Locale']); - } - - public function addTranslationArray($translation) - { - if(!isset($GLOBALS['Piwik_translations'])) - { - $GLOBALS['Piwik_translations'] = array(); - } - // we could check that no string overlap here - $GLOBALS['Piwik_translations'] = array_merge($GLOBALS['Piwik_translations'], $translation); - } - - /** - * @return string the language filename prefix, eg "en" for english - * @throws exception if the language set in the config file is not a valid filename - */ - public function getLanguageToLoad() - { - $language = Zend_Registry::get('config')->Language->current; - - if( Piwik_Common::isValidFilename($language)) - { - return $language; - } - else - { - throw new Exception("The language selected ('$language') is not a valid language file "); - } - } - - protected function getFallbackLanguageToLoad() - { - return Zend_Registry::get('config')->Language->fallback; - } - - /** - * Generate javascript translations array - * - * @return string containing javascript code with translations array (including <script> tag) - * - */ - public function getJavascriptTranslations($moduleList) - { - if( !$moduleList ) - { - return ''; - } - - $js = 'var translations = {'; - - $moduleRegex = '#^('; - foreach($moduleList as $module) - { - $moduleRegex .= $module.'|'; - } - $moduleRegex = substr($moduleRegex, 0, -1); - $moduleRegex .= ')_([^_]+)_js$#i'; - - foreach($GLOBALS['Piwik_translations'] as $key => $value) - { - $matches = array(); - - if( preg_match($moduleRegex,$key,$matches) ) { - $varName = $matches[1].'_'.$matches[2]; - $varValue = $value; - - $js .= "".$varName.": '".str_replace("'","\\'",$varValue)."',"; - } - - $matches = null; - } - $js = substr($js,0,-1); - $js .= '};'; - $js .= 'function _pk_translate(tvar, str) { '. - 'var s = str; if( typeof(translations[tvar]) != \'undefined\' ) s = translations[tvar];'. - 'return s;}'; - - return $js; - } -} - -function Piwik_Translate($index) -{ - if(isset($GLOBALS['Piwik_translations'][$index])) - { - return $GLOBALS['Piwik_translations'][$index]; - } - throw new Exception("Translation string '$index' not available."); -} - - -/** - * Returns translated string or given message if translation is not found. - * This function does not throw any exception. Use it to translate exceptions. - * - * @param string Translation string index - * @return string - */ -function Piwik_TranslateException($message) -{ - try { - return Piwik_Translate($message); - } - catch(Exception $e) { - return $message; - } -} - - diff --git a/modules/Url.php b/modules/Url.php deleted file mode 100644 index 4ff8127ea3..0000000000 --- a/modules/Url.php +++ /dev/null @@ -1,159 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_Helper - */ - -/** - * @package Piwik_Helper - * - */ -class Piwik_Url -{ - static function getArrayFromCurrentQueryString() - { - $queryString = Piwik_Url::getCurrentQueryString(); - $queryString = htmlspecialchars($queryString); - $urlValues = Piwik_Common::getArrayFromQueryString($queryString); - return $urlValues; - } - - static function getCurrentQueryStringWithParametersModified( $params ) - { - $urlValues = self::getArrayFromCurrentQueryString(); - - foreach($params as $key => $value) - { - $urlValues[$key] = $value; - } - - $query = http_build_query($urlValues, "", "&"); - - if(strlen($query) > 0) - { - return '?'.$query; - } - else - { - return ''; - } - } - - static public function redirectToUrl( $url ) - { - header("Location: $url"); - exit; - } - - static public function getReferer() - { - if(!empty($_SERVER['HTTP_REFERER'])) - { - return $_SERVER['HTTP_REFERER']; - } - return false; - } - - static public function getCurrentUrl() - { - return self::getCurrentHost() - . self::getCurrentScriptName() - . self::getCurrentQueryString(); - } - - static public function getCurrentUrlWithoutQueryString() - { - - return self::getCurrentHost() - . self::getCurrentScriptName() ; - } - - /** - * Ending with / - */ - static public function getCurrentUrlWithoutFileName() - { - - $host = self::getCurrentHost(); - $queryString = self::getCurrentScriptName() ; - - //add a fake letter case /test/test2/ returns /test which is not expected - $urlDir = dirname ($queryString . 'x'); - // if we are in a subpath we add a trailing slash - if(strlen($urlDir) > 1) - { - $urlDir .= '/'; - } - return $host.$urlDir; - } - - 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 .= '://'; - - if(isset($_SERVER['HTTP_HOST'])) - { - $url .= $_SERVER['HTTP_HOST']; - } - else - { - $url .= 'unknown'; - } - return $url; - } - - - static public function getCurrentQueryString() - { - $url = ''; - if(isset($_SERVER['QUERY_STRING']) - && !empty($_SERVER['QUERY_STRING'])) - { - $url .= "?".$_SERVER['QUERY_STRING']; - } - return $url; - } -} - diff --git a/modules/View.php b/modules/View.php deleted file mode 100644 index b0c2ea0d20..0000000000 --- a/modules/View.php +++ /dev/null @@ -1,136 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_Visualization - */ - -require_once 'Smarty/Smarty.class.php'; - -require_once "iView.php"; - -/** - * - * @package Piwik_Visualization - * - */ -class Piwik_View implements Piwik_iView -{ - private $template = ''; - private $smarty = false; - private $variables = array(); - - public function __construct( $templateFile, $smConf = array()) - { - $this->template = $templateFile; - $this->smarty = new Smarty(); - - if(count($smConf) == 0) - { - $smConf = Zend_Registry::get('config')->smarty; - } - foreach($smConf as $key => $value) - { - $this->smarty->$key = $value; - } - - $this->smarty->template_dir = $smConf->template_dir->toArray(); - $this->smarty->plugins_dir = $smConf->plugins_dir->toArray(); - $this->smarty->compile_dir = $smConf->compile_dir; - $this->smarty->cache_dir = $smConf->cache_dir; - - $this->smarty->load_filter('output','trimwhitespace'); - - // global value accessible to all templates: the piwik base URL for the current request - $this->piwikUrl = Piwik_Url::getCurrentUrlWithoutFileName(); - - } - - /** - * Directly assigns a variable to the view script. - * VAR names may not be prefixed with '_'. - * @param string $key The variable name. - * @param mixed $val The variable value. - * @return void - */ - public function __set($key, $val) - { - $this->smarty->assign($key, $val); - } - - /** - * Retrieves an assigned variable. - * VAR names may not be prefixed with '_'. - * @param string $key The variable name. - * @return mixed The variable value. - */ - public function __get($key) - { - return $this->smarty->get_template_vars($key); - } - - public function render() - { - $this->totalTimeGeneration = Zend_Registry::get('timer')->getTime(); - - try { - $this->totalNumberOfQueries = Piwik::getQueryCount(); - } - catch(Exception $e){ - $this->totalNumberOfQueries = 0; - } - - header('Content-Type: text/html; charset=utf-8'); - - return $this->smarty->fetch($this->template); - - } - - public function addForm( $form ) - { - // Create the renderer object - $renderer = new HTML_QuickForm_Renderer_ArraySmarty($this->smarty); - - // build the HTML for the form - $form->accept($renderer); - - // assign array with form data - $this->smarty->assign('form_data', $renderer->toArray()); - $this->smarty->assign('element_list', $form->getElementList()); - } - - public function assign($var, $value=null) - { - if (is_string($var)) - { - $this->smarty->assign($var, $value); - } - elseif (is_array($var)) - { - foreach ($var as $key => $value) - { - $this->smarty->assign($key, $value); - } - } - } - -/* public function isCached($template) - { - if ($this->smarty->is_cached($template)) - { - return true; - } - return false; - } - - - public function setCaching($caching) - { - $this->smarty->caching = $caching; - } -*/ -}
\ No newline at end of file diff --git a/modules/ViewDataTable.php b/modules/ViewDataTable.php deleted file mode 100644 index cdd27680b9..0000000000 --- a/modules/ViewDataTable.php +++ /dev/null @@ -1,798 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_ViewDataTable - */ - -require_once "API/Request.php"; - -/** - * This class is used to load (from the API) and customize the output of a given DataTable. - * The main() method will create an object Piwik_iView - * You can customize the dataTable using the disable* methods. - * - * Example: - * In the Controller of the plugin VisitorInterest - * <pre> - * function getNumberOfVisitsPerVisitDuration( $fetch = false) - * { - * $view = Piwik_ViewDataTable::factory( 'cloud' ); - * $view->init( $this->pluginName, __FUNCTION__, 'VisitorInterest.getNumberOfVisitsPerVisitDuration' ); - * $view->setColumnsToDisplay( array('label','nb_visits') ); - * $view->disableSort(); - * $view->disableExcludeLowPopulation(); - * $view->disableOffsetInformation(); - * - * return $this->renderView($view, $fetch); - * } - * </pre> - * - * @see factory() for all the available output (cloud tags, html table, pie chart, vertical bar chart) - * @package Piwik_ViewDataTable - * - */ - -abstract class Piwik_ViewDataTable -{ - /** - * Template file that will be loaded for this view. - * Usually set in the Piwik_ViewDataTable_* - * - * @var string eg. 'CoreHome/templates/cloud.tpl' - */ - protected $dataTableTemplate = null; - - /** - * Flag used to make sure the main() is only executed once - * - * @var bool - */ - protected $mainAlreadyExecuted = false; - - /** - * Defines if we display the search box under the table - * - * @see disableSearchBox() - * @see getSearchBox() - * - * @var bool - */ - protected $JSsearchBox = true; - - /** - * Defines if we display the "X-Y of Z" under the table - * - * @see disableOffsetInformation() - * @see getOffsetInformation() - * - * @var bool - */ - protected $JSoffsetInformation = true; - - /** - * Defines if we display the "Include all population" link under the table - * - * @see disableExcludeLowPopulation() - * @see getExcludeLowPopulation() - * - * @var bool - */ - protected $JSexcludeLowPopulation = true; - - /** - * Defines if we include the footer after the dataTable output. - * The footer contains all the extra features like the search box, the links Next/Previous, the icons to export in several formats, etc. - * Not showing the footer is useful for example when you want to only display a graph without anything else. - * - * @see doNotShowFooter() - * @see getShowFooter() - * - * @var bool - */ - protected $showFooter = true; - - /** - * Contains the values set for the parameters - * @see getJavascriptVariablesToSet() - * - * @var array - */ - protected $variablesDefault = array(); - - /** - * If the current dataTable refers to a subDataTable (eg. keywordsBySearchEngineId for id=X) this variable is set to the Id - * - * @var bool|int - */ - protected $idSubtable = false; - - /** - * Set to true when the DataTable must be loaded along with all its children subtables - * Useful when searching for a pattern in the DataTable Actions (we display the full hierarchy) - * - * @var bool - */ - protected $recursiveDataTableLoad = false; - - /** - * DataTable loaded from the API for this ViewDataTable. - * - * @var Piwik_DataTable - */ - protected $dataTable = null; - - /** - * @see init() - * - * @var string - */ - protected $currentControllerAction; - - /** - * @see init() - * - * @var string - */ - protected $currentControllerName; - - /** - * @see init() - * - * @var string - */ - protected $actionToLoadTheSubTable = null; - - /** - * @see init() - * - * @var string - */ - protected $moduleNameAndMethod; - - /** - * This view should be an implementation of the Interface Piwik_iView - * The $view object should be created in the main() method. - * - * @var Piwik_iView - */ - protected $view = null; - - /** - * Method to be implemented by the ViewDataTable_*. - * This method should create and initialize a $this->view object @see Piwik_iView - * - * @return mixed either prints the result or returns the output string - */ - abstract public function main(); - - /** - * Returns a Piwik_ViewDataTable_* object. - * By default it will return a ViewDataTable_Html - * If there is a viewDataTable parameter in the URL, a ViewDataTable of this 'viewDataTable' type will be returned. - * If defaultType is specified and if there is no 'viewDataTable' in the URL, a ViewDataTable of this $defaultType will be returned. - * If force is set to true, a ViewDataTable of the $defaultType will be returned in all cases. - * - * @param string defaultType Any of these: table, cloud, graphPie, graphVerticalBar, graphEvolution, sparkline, generateDataChart* - * @force bool If set to true, returns a ViewDataTable of the $defaultType - * - * @return Piwik_ViewDataTable - */ - static public function factory( $defaultType = null, $force = false) - { - if(is_null($defaultType)) - { - $defaultType = 'table'; - } - - if($force === true) - { - $type = $defaultType; - } - else - { - $type = Piwik_Common::getRequestVar('viewDataTable', $defaultType, 'string'); - } - - switch($type) - { - case 'cloud': - require_once "ViewDataTable/Cloud.php"; - return new Piwik_ViewDataTable_Cloud(); - break; - - case 'graphPie': - require_once "ViewDataTable/GenerateGraphHTML/ChartPie.php"; - return new Piwik_ViewDataTable_GenerateGraphHTML_ChartPie(); - break; - - case 'graphVerticalBar': - require_once "ViewDataTable/GenerateGraphHTML/ChartVerticalBar.php"; - return new Piwik_ViewDataTable_GenerateGraphHTML_ChartVerticalBar(); - break; - - case 'graphEvolution': - require_once "ViewDataTable/GenerateGraphHTML/ChartEvolution.php"; - return new Piwik_ViewDataTable_GenerateGraphHTML_ChartEvolution(); - break; - - case 'sparkline': - require_once "ViewDataTable/Sparkline.php"; - return new Piwik_ViewDataTable_Sparkline(); - break; - - case 'generateDataChartVerticalBar': - require_once "ViewDataTable/GenerateGraphData/ChartVerticalBar.php"; - return new Piwik_ViewDataTable_GenerateGraphData_ChartVerticalBar(); - break; - - case 'generateDataChartPie': - require_once "ViewDataTable/GenerateGraphData/ChartPie.php"; - return new Piwik_ViewDataTable_GenerateGraphData_ChartPie(); - break; - - case 'generateDataChartEvolution': - require_once "ViewDataTable/GenerateGraphData/ChartEvolution.php"; - return new Piwik_ViewDataTable_GenerateGraphData_ChartEvolution(); - - break; - - case 'table': - default: - require_once "ViewDataTable/Html.php"; - return new Piwik_ViewDataTable_Html(); - break; - } - } - - /** - * Inits the object given the $currentControllerName, $currentControllerAction of - * the calling controller action, eg. 'Referers' 'getLongListOfKeywords'. - * The initialization also requires the $moduleNameAndMethod of the API method - * to call in order to get the DataTable, eg. 'Referers.getKeywords'. - * The optional $actionToLoadTheSubTable defines the method name of the API to call when there is a idSubtable. - * This value would be used by the javascript code building the GET request to the API. - * - * Example: - * For the keywords listing, a click on the row loads the subTable of the Search Engines for this row. - * In this case $actionToLoadTheSubTable = 'getSearchEnginesFromKeywordId'. - * The GET request will hit 'Referers.getSearchEnginesFromKeywordId'. - * - * @param string $currentControllerName eg. 'Referers' - * @param string $currentControllerAction eg. 'getKeywords' - * @param string $moduleNameAndMethod eg. 'Referers.getKeywords' - * @param string $actionToLoadTheSubTable eg. 'getSearchEnginesFromKeywordId' - * - * @return void - */ - public function init( $currentControllerName, - $currentControllerAction, - $moduleNameAndMethod, - $actionToLoadTheSubTable = null) - { - $this->currentControllerName = $currentControllerName; - $this->currentControllerAction = $currentControllerAction; - $this->moduleNameAndMethod = $moduleNameAndMethod; - $this->actionToLoadTheSubTable = $actionToLoadTheSubTable; - - $this->idSubtable = Piwik_Common::getRequestVar('idSubtable', false, 'int'); - - $this->method = $moduleNameAndMethod; - - $this->JSsearchBox = Piwik_Common::getRequestVar('show_search', true); - $this->showFooter = Piwik_Common::getRequestVar('showDataTableFooter', true); - $this->variablesDefault['filter_excludelowpop_default'] = 'false'; - $this->variablesDefault['filter_excludelowpop_value_default'] = 'false'; - } - - /** - * Forces the View to use a given template. - * Usually the template to use is set in the specific ViewDataTable_* - * eg. 'CoreHome/templates/cloud.tpl' - * - * But some users may want to force this template to some other value - * - * @param string $tpl eg .'MyPlugin/templates/templateToUse.tpl' - */ - public function setTemplate( $tpl ) - { - $this->dataTableTemplate = $tpl; - } - - /** - * Returns the iView. - * You can then call render() on this object. - * - * @return Piwik_iView - * @throws exception if the view object was not created - */ - public function getView() - { - if(is_null($this->view)) - { - throw new Exception('The $this->view object has not been created. - It should be created in the main() method of the Piwik_ViewDataTable_* subclass you are using.'); - } - return $this->view; - } - - /** - * Returns the DataTable loaded from the API - * - * @return Piwik_DataTable - * @throws exception if not yet defined - */ - public function getDataTable() - { - if(is_null($this->dataTable)) - { - throw new Exception("The DataTable requested has not been loaded yet."); - } - return $this->dataTable; - } - /** - * Function called by the ViewDataTable objects in order to fetch data from the API. - * The function init() must have been called before, so that the object knows which API module and action to call. - * It builds the API request string and uses Piwik_API_Request to call the API. - * The requested Piwik_DataTable object is stored in $this->dataTable. - * - * @return void - */ - protected function loadDataTableFromAPI() - { - // we prepare the string to give to the API Request - // we setup the method and format variable - // - we request the method to call to get this specific DataTable - // - the format = original specifies that we want to get the original DataTable structure itself, not rendered - $requestString = 'method='.$this->moduleNameAndMethod - .'&format=original' - ; - if( $this->recursiveDataTableLoad ) - { - $requestString .= '&expanded=1'; - } - - $toSetEventually = array( - 'filter_limit', - 'filter_sort_column', - 'filter_sort_order', - 'filter_excludelowpop', - 'filter_excludelowpop_value', - 'filter_column', - 'filter_pattern', - 'disable_generic_filters', - 'disable_queued_filters', - ); - foreach($toSetEventually as $varToSet) - { - $value = $this->getDefaultOrCurrent($varToSet); - if( false !== $value ) - { - $requestString .= '&'.$varToSet.'='.$value; - } - } - - // We finally make the request to the API - $request = new Piwik_API_Request($requestString); - - // and get the DataTable structure - $dataTable = $request->process(); - - $this->dataTable = $dataTable; - } - - - /** - * For convenience, the client code can call methods that are defined in a specific children class - * without testing the children class type, which would trigger an error with a different children class. - * - * Example: - * ViewDataTable/Html.php defines a setColumnsToDisplay(). The client code calls this methods even if - * the ViewDataTable object is a ViewDataTable_Cloud instance (he doesn't know because of the factory()). - * But ViewDataTable_Cloud doesn't define the setColumnsToDisplay() method. - * Because we don't want to force users to test for the object type we simply catch these - * calls when they are not defined in the child and do nothing. - * - * @param string $function - * @param array $args - */ - public function __call($function, $args) - { - } - - /** - * Returns a unique ID for this ViewDataTable. - * This unique ID is used in the Javascript code: - * Any ajax loaded data is loaded within a DIV that has id=$unique_id - * The jquery code then replaces the existing html div id=$unique_id in the code with this data. - * - * @see datatable.js - * @return string - */ - protected function getUniqIdTable() - { - // if we request a subDataTable the $this->currentControllerAction DIV ID is already there in the page - // we make the DIV ID really unique by appending the ID of the subtable requested - if( $this->idSubtable != 0 // parent DIV has a idSubtable = 0 but the html DIV must have the name of the module.action - && $this->idSubtable !== false // case there is no idSubtable - ) - { - // see also datatable.js (the ID has to match with the html ID created to be replaced by the result of the ajax call) - $uniqIdTable = 'subDataTable_' . $this->idSubtable; - } - else - { - // the $uniqIdTable variable is used as the DIV ID in the rendered HTML - // we use the current Controller action name as it is supposed to be unique in the rendered page - $uniqIdTable = $this->currentControllerName . $this->currentControllerAction; - } - return $uniqIdTable; - } - - /** - * This functions reads the customization values for the DataTable and returns an array (name,value) to be printed in Javascript. - * This array defines things such as: - * - name of the module & action to call to request data for this table - * - display the search box under the table - * - display the links Next & Previous under the table - * - optional filters information, eg. filter_limit and filter_offset - * - etc. - * - * The values are loaded: - * - from the generic filters that are applied by default @see Piwik_API_Request::getGenericFiltersInformation() - * - from the values already available in the GET array - * - from the values set using methods from this class (eg. setSearchPattern(), setLimit(), etc.) - * - * @return array eg. array('show_offset_information' => 0, 'show_ - */ - protected function getJavascriptVariablesToSet() - { - // build javascript variables to set - $javascriptVariablesToSet = array(); - - $genericFilters = Piwik_API_Request::getGenericFiltersInformation(); - foreach($genericFilters as $filter) - { - foreach($filter as $filterVariableName => $filterInfo) - { - // if there is a default value for this filter variable we set it - // so that it is propagated to the javascript - if(isset($filterInfo[1])) - { - $javascriptVariablesToSet[$filterVariableName] = $filterInfo[1]; - - // we set the default specified column and Order to sort by - // when this javascript variable is not set already - // for example during an AJAX call this variable will be set in the URL - // so this will not be executed (and the default sorted not be used as the sorted column might have changed in the meanwhile) - if( false !== ($defaultValue = $this->getDefault($filterVariableName))) - { - $javascriptVariablesToSet[$filterVariableName] = $defaultValue; - } - } - } - } - - foreach($_GET as $name => $value) - { - try{ - $requestValue = Piwik_Common::getRequestVar($name); - } - catch(Exception $e) { - $requestValue = ''; - } - $javascriptVariablesToSet[$name] = $requestValue; - } - - // at this point there are some filters values we may have not set, - // case of the filter without default values and parameters set directly in this class - // for example setExcludeLowPopulation - // we go through all the $this->variablesDefault array and set the variables not set yet - foreach($this->variablesDefault as $name => $value) - { - if(!isset($javascriptVariablesToSet[$name] )) - { - $javascriptVariablesToSet[$name] = $value; - } - } - - $javascriptVariablesToSet['module'] = $this->currentControllerName; - $javascriptVariablesToSet['action'] = $this->currentControllerAction; - - if(!is_null($this->actionToLoadTheSubTable)) - { - $javascriptVariablesToSet['actionToLoadTheSubTable'] = $this->actionToLoadTheSubTable; - } - -// var_dump($this->variablesDefault); -// var_dump($javascriptVariablesToSet); exit; - - if($this->dataTable) - { - $javascriptVariablesToSet['totalRows'] = $this->dataTable->getRowsCountBeforeLimitFilter(); - } - $javascriptVariablesToSet['show_search'] = $this->getSearchBox(); - $javascriptVariablesToSet['show_offset_information'] = $this->getOffsetInformation(); - $javascriptVariablesToSet['show_exclude_low_population'] = $this->getExcludeLowPopulation(); - - // we escape the values that will be displayed in the javascript footer of each datatable - // to make sure there is malicious code injected (the value are already htmlspecialchar'ed as they - // are loaded with Piwik_Common::getRequestVar() - foreach($javascriptVariablesToSet as &$value) - { - $value = addslashes($value); - } - - return $javascriptVariablesToSet; - } - - /** - * Returns, for a given parameter, the value of this parameter in the REQUEST array. - * If not set, returns the default value for this parameter @see getDefault() - * - * @param string $nameVar - * @return string|mixed Value of this parameter - */ - protected function getDefaultOrCurrent( $nameVar ) - { - if(isset($_REQUEST[$nameVar])) - { - return $_REQUEST[$nameVar]; - } - $default = $this->getDefault($nameVar); - return $default; - } - - /** - * Returns the default value for a given parameter. - * For example, these default values can be set using the disable* methods. - * - * @param string $nameVar - * @return mixed - */ - protected function getDefault($nameVar) - { - if(!isset($this->variablesDefault[$nameVar])) - { - return false; - } - return $this->variablesDefault[$nameVar]; - } - - /** - * The generic filters (limit, offset, sort by visit desc) will not be applied to this datatable. - * - * @return void - * - */ - public function disableGenericFilters() - { - $this->variablesDefault['disable_generic_filters'] = true; - } - /** - * The "X-Y of Z" won't be displayed under this table - * - * @return void - * - */ - public function disableOffsetInformation() - { - $this->JSoffsetInformation = 'false'; - } - - /** - * @see disableOffsetInformation() - * - * @return bool|string If this parameter is enabled or not - * - */ - protected function getOffsetInformation() - { - return $this->JSoffsetInformation; - } - - /** - * The search box won't be displayed under this table - * - * @return void - */ - public function disableSearchBox() - { - $this->JSsearchBox = 'false'; - } - - /** - * @see disableSearchBox() - * - * @return bool|string If this parameter is enabled or not - * - */ - protected function getSearchBox() - { - return $this->JSsearchBox; - } - - /** - * When this method is called, the output will not contain the template datatable_footer.tpl - * - * @return void - */ - public function doNotShowFooter() - { - $this->showFooter = false; - } - - /** - * Returns true if the footer should be included in the template - * - * @return bool - * - */ - protected function getShowFooter() - { - return $this->showFooter; - } - - /** - * The "Include low population" link won't be displayed under this table - * - * @return void - */ - public function disableExcludeLowPopulation() - { - $this->JSexcludeLowPopulation = 'false'; - } - - /** - * @see disableExcludeLowPopulation() - * - * @return bool|string If this parameter is enabled or not - * - */ - protected function getExcludeLowPopulation() - { - return $this->JSexcludeLowPopulation; - } - - - /** - * Sets the value to use for the Exclude low population filter. - * - * @param int|float If a row value is less than this value, it will be removed from the dataTable - * @param string The name of the column for which we compare the value to $minValue - * - * @return void - */ - public function setExcludeLowPopulation( $minValue = null, $columnName = null ) - { - if( is_null( $minValue) ) - { - throw new Exception("setExcludeLowPopulation() value shouldn't be null"); - } - - if(is_null($columnName)) - { - $columnName = Piwik_Archive::INDEX_NB_VISITS; - } - - // column to use to enable low population exclusion if != false - $this->variablesDefault['filter_excludelowpop_default'] - = $this->variablesDefault['filter_excludelowpop'] - = $columnName; - - // the minimum value a row must have to be returned - $this->variablesDefault['filter_excludelowpop_value_default'] - = $this->variablesDefault['filter_excludelowpop_value'] - = $minValue; - } - - /** - * Sets the pattern to look for in the table (only rows matching the pattern will be kept) - * - * @param string $pattern to look for - * @param string $column to compare the pattern to - * - * @return void - */ - public function setSearchPattern($pattern, $column) - { - $this->variablesDefault['filter_pattern'] = $pattern; - $this->variablesDefault['filter_column'] = $column; - } - - /** - * Sets the maximum number of rows of the table - * - * @param int $limit - * - * @return void - */ - public function setLimit( $limit ) - { - if($limit != 0) - { - $this->variablesDefault['filter_limit'] = $limit; - } - } - - /** - * Sets the dataTable column to sort by. This sorting will be applied before applying the (offset, limit) filter. - * - * @param int|string $columnId eg. 'nb_visits' for some tables, or Piwik_Archive::INDEX_NB_VISITS for others - * @param string $order desc or asc - * - * @return void - */ - public function setSortedColumn( $columnId, $order = 'desc') - { - $this->variablesDefault['filter_sort_column']= $columnId; - $this->variablesDefault['filter_sort_order']= $order; - } - - - /** - * Given a Piwik_DataTable_Array made of DataTable_Simple rows, returns a php array with the structure: - * array( - * array( label => X, value => Y), - * array( label => A, value => B), - * ... - * ) - * - * This is used for example for the evolution graph (last 30 days visits) or the sparklines. - * - * @param Piwik_DataTable_Array $dataTableArray - * @return array - */ - protected function generateDataFromDataTableArray( Piwik_DataTable_Array $dataTableArray) - { - $data = array(); - foreach($dataTableArray->getArray() as $keyName => $table) - { - if($table instanceof Piwik_DataTable_Array) - { - throw new Exception("Operation not supported (yet)"); - } - $value = false; - - $onlyRow = $table->getFirstRow(); - if($onlyRow !== false) - { - $value = $onlyRow->getColumn('value'); - if($value == false) - { - // TEMP - // quite a hack, useful in the case at this point we do have a normal row with nb_visits, nb_actions, nb_uniq_visitors, etc. - // instead of the dataTable_Simple row (label, value) - // to do it properly we'd need to - // - create a filter that removes columns - // - apply this filter to keep only the column called nb_uniq_visitors - // - rename this column as 'value' - // and at this point the getcolumn('value') would have worked - // this code is executed eg. when displaying a sparkline for the last 30 days displaying the number of unique visitors coming from search engines - - //TODO solution: use a filter rename column etc. - - // another solution would be to add a method to the Referers API giving directly the integer 'visits from search engines' - // and we would build automatically the dataTable_array of datatatble_simple from these integers - // but we'd have to add this integer to be recorded during archiving etc. - $value = $onlyRow->getColumn('nb_uniq_visitors'); - } - } - - if($value === false) - { - $value = 0; - } - $data[] = array( - 'label' => $keyName, - 'value' => $value - ); - } - return $data; - } - -}
\ No newline at end of file diff --git a/modules/ViewDataTable/Cloud.php b/modules/ViewDataTable/Cloud.php deleted file mode 100644 index c8ac15a986..0000000000 --- a/modules/ViewDataTable/Cloud.php +++ /dev/null @@ -1,108 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_ViewDataTable - */ - -require_once "Visualization/Cloud.php"; - -/** - * Reads the requested DataTable from the API, and prepares the data to give - * to Piwik_Visualization_Cloud that will display the tag cloud (via the template cloud.tpl). - * - * @package Piwik_ViewDataTable - * - */ -class Piwik_ViewDataTable_Cloud extends Piwik_ViewDataTable -{ - //TODO test this - protected $displayLogoInsteadOfLabel = false; - - /** - * @see Piwik_ViewDataTable::init() - */ - function init($currentControllerName, - $currentControllerAction, - $moduleNameAndMethod ) - { - parent::init($currentControllerName, - $currentControllerAction, - $moduleNameAndMethod ); - $this->dataTableTemplate = 'CoreHome/templates/cloud.tpl'; - - $this->disableOffsetInformation(); - $this->disableExcludeLowPopulation(); - } - - /** - * @see Piwik_ViewDataTable::main() - * - */ - public function main() - { - $this->setLimit( 30 ); - if($this->mainAlreadyExecuted) - { - return; - } - $this->mainAlreadyExecuted = true; - - $this->loadDataTableFromAPI(); - - // We apply a filter to the DataTable, decoding the label column (useful for keywords for example) - $filter = new Piwik_DataTable_Filter_ColumnCallbackReplace( - $this->dataTable, - 'label', - 'urldecode' - ); - - - $view = new Piwik_View($this->dataTableTemplate); - - $words = $labelMetadata = array(); - foreach($this->dataTable->getRows() as $row) - { - $label = $row->getColumn('label'); - $value = $row->getColumn('nb_uniq_visitors'); - - // case no unique visitors - if($value === false) - { - $value = $row->getColumn('nb_visits'); - } - $words[$label] = $value; - - $logo = false; - if($this->displayLogoInsteadOfLabel) - { - $logo = $row->getMetadata('logo'); - } - - $labelMetadata[$label] = array( - 'logo' => $logo, - 'url' => $row->getMetadata('url'), - 'hits' => $value - ); - } - $cloud = new Piwik_Visualization_Cloud($words); - $cloudValues = $cloud->render('array'); - - foreach($cloudValues as &$value) - { - $value['logoWidth'] = round(max(16, $value['percent'])); - } - $view->labelMetadata = $labelMetadata; - $view->cloudValues = $cloudValues; - - $view->method = $this->method; - $view->id = $this->getUniqIdTable(); - $view->javascriptVariablesToSet = $this->getJavascriptVariablesToSet(); - $view->showFooter = $this->getShowFooter(); - $this->view = $view; - } -} diff --git a/modules/ViewDataTable/GenerateGraphData.php b/modules/ViewDataTable/GenerateGraphData.php deleted file mode 100644 index c6433202ea..0000000000 --- a/modules/ViewDataTable/GenerateGraphData.php +++ /dev/null @@ -1,140 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_ViewDataTable - */ - -/** - * Reads data from the API and prepares data to give to the renderer Piwik_Visualization_Chart. - * This class is used to generate the data for the FLASH charts. It is given as a parameter of the SWF file. - * You can set the number of elements to appear in the graph using: setGraphLimit(); - * Example: - * <pre> - * function getWebsites( $fetch = false) - * { - * $view = Piwik_ViewDataTable::factory(); - * $view->init( $this->pluginName, 'getWebsites', 'Referers.getWebsites', 'getUrlsFromWebsiteId' ); - * $view->setColumnsToDisplay( array('label','nb_visits') ); - * $view->setLimit(10); - * $view->setGraphLimit(12); - * return $this->renderView($view, $fetch); - * } - * </pre> - * - * @package Piwik_ViewDataTable - * - */ -abstract class Piwik_ViewDataTable_GenerateGraphData extends Piwik_ViewDataTable -{ - /** - * @see Piwik_ViewDataTable::init() - */ - function init($currentControllerName, - $currentControllerAction, - $moduleNameAndMethod ) - { - parent::init($currentControllerName, - $currentControllerAction, - $moduleNameAndMethod ); - } - - /** - * Number of elements to display in the graph. - * - * @var int - */ - protected $graphLimit = 5; - - /** - * Sets the number max of elements to display (number of pie slice, vertical bars, etc.) - * If the data has more elements than $limit then the last part of the data will be the sum of all the remaining data. - * - * @param int $limit - */ - function setGraphLimit( $limit ) - { - $this->graphLimit = $limit; - } - /** - * Returns numbers of elemnts to display in the graph - * - * @return int - */ - function getGraphLimit() - { - return $this->graphLimit; - } - - public function main() - { - if($this->mainAlreadyExecuted) - { - return; - } - $this->mainAlreadyExecuted = true; - - $this->setLimit(-1); - - // we load the data with the filters applied - $this->loadDataTableFromAPI(); - $offsetStartSummary = $this->getGraphLimit() - 1; - $this->dataTable->queueFilter('Piwik_DataTable_Filter_AddSummaryRow', array($offsetStartSummary, Piwik_Translate('General_Others'))); - $this->dataAvailable = $this->dataTable->getRowsCount() != 0; - - if(!$this->dataAvailable) - { - $this->view->customizeGraph(); - $this->view->title(Piwik_Translate('General_NoDataForGraph'), '{font-size: 25px;}'); - } - else - { - $data = $this->generateDataFromDataTable(); - $this->view->setData($data); - $this->view->customizeGraph(); - } - } - - /** - * Returns a format friendly array from the dataTable - * - * @return array - */ - protected function generateDataFromDataTable() - { - $this->dataTable->applyQueuedFilters(); - - // We apply a filter to the DataTable, decoding the label column (useful for keywords for example) - $filter = new Piwik_DataTable_Filter_ColumnCallbackReplace( - $this->dataTable, - 'label', - 'urldecode' - ); - $data = array(); - foreach($this->dataTable->getRows() as $row) - { - $label = $row->getColumn('label'); - $value = $row->getColumn('nb_uniq_visitors'); - - // case no unique visitors - if($value === false) - { - $value = $row->getColumn('nb_visits'); - } - - $data[] = array( - 'label' => $label, - 'value' => $value, - 'url' => $row->getMetadata('url'), - ); - } - return $data; - } -} - - - diff --git a/modules/ViewDataTable/GenerateGraphData/ChartEvolution.php b/modules/ViewDataTable/GenerateGraphData/ChartEvolution.php deleted file mode 100644 index 70bf412f57..0000000000 --- a/modules/ViewDataTable/GenerateGraphData/ChartEvolution.php +++ /dev/null @@ -1,21 +0,0 @@ -<?php -require_once "ViewDataTable/GenerateGraphData.php"; -/** - * Piwik_ViewDataTable_GenerateGraphData for the Evolution graph (eg. Last 30 days visits) using Piwik_Visualization_ChartEvolution - * - * @package Piwik_ViewDataTable - * - */ -class Piwik_ViewDataTable_GenerateGraphData_ChartEvolution extends Piwik_ViewDataTable_GenerateGraphData -{ - function __construct() - { - require_once "Visualization/ChartEvolution.php"; - $this->view = new Piwik_Visualization_ChartEvolution; - } - - protected function generateDataFromDataTable() - { - return $this->generateDataFromDataTableArray($this->dataTable); - } -} diff --git a/modules/ViewDataTable/GenerateGraphData/ChartPie.php b/modules/ViewDataTable/GenerateGraphData/ChartPie.php deleted file mode 100644 index 53739067c8..0000000000 --- a/modules/ViewDataTable/GenerateGraphData/ChartPie.php +++ /dev/null @@ -1,16 +0,0 @@ -<?php -require_once "ViewDataTable/GenerateGraphData.php"; -/** - * Piwik_ViewDataTable_GenerateGraphData for the pie chart, using Piwik_Visualization_ChartPie - * - * @package Piwik_ViewDataTable - * - */ -class Piwik_ViewDataTable_GenerateGraphData_ChartPie extends Piwik_ViewDataTable_GenerateGraphData -{ - function __construct() - { - require_once "Visualization/ChartPie.php"; - $this->view = new Piwik_Visualization_ChartPie; - } -}
\ No newline at end of file diff --git a/modules/ViewDataTable/GenerateGraphData/ChartVerticalBar.php b/modules/ViewDataTable/GenerateGraphData/ChartVerticalBar.php deleted file mode 100644 index 1bb9ea27b2..0000000000 --- a/modules/ViewDataTable/GenerateGraphData/ChartVerticalBar.php +++ /dev/null @@ -1,16 +0,0 @@ -<?php -require_once "ViewDataTable/GenerateGraphData.php"; -/** - * Piwik_ViewDataTable_GenerateGraphData for the vertical bar graph, using Piwik_Visualization_ChartVerticalBar - * - * @package Piwik_ViewDataTable - * - */ -class Piwik_ViewDataTable_GenerateGraphData_ChartVerticalBar extends Piwik_ViewDataTable_GenerateGraphData -{ - function __construct() - { - require_once "Visualization/ChartVerticalBar.php"; - $this->view = new Piwik_Visualization_ChartVerticalBar; - } -}
\ No newline at end of file diff --git a/modules/ViewDataTable/GenerateGraphHTML.php b/modules/ViewDataTable/GenerateGraphHTML.php deleted file mode 100644 index 167a4fc214..0000000000 --- a/modules/ViewDataTable/GenerateGraphHTML.php +++ /dev/null @@ -1,139 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_ViewDataTable - */ - -/** - * This class generates the HTML code to embed to flash graphs in the page. - * It doesn't call the API but simply prints the html snippet. - * - * @package Piwik_ViewDataTable - * - */ -abstract class Piwik_ViewDataTable_GenerateGraphHTML extends Piwik_ViewDataTable -{ - protected $width = '100%'; - protected $height = 250; - protected $graphType = 'standard'; - - /** - * @see Piwik_ViewDataTable::init() - * - */ - function init($currentControllerName, - $currentControllerAction, - $moduleNameAndMethod ) - { - parent::init($currentControllerName, - $currentControllerAction, - $moduleNameAndMethod ); - $this->dataTableTemplate = 'CoreHome/templates/graph.tpl'; - - $this->disableOffsetInformation(); - $this->disableExcludeLowPopulation(); - $this->disableSearchBox(); - $this->parametersToModify = array( - 'viewDataTable' => $this->valueParameterViewDataTable, - // in the case this controller is being executed by another controller - // eg. when being widgetized in an IFRAME - // we need to put in the URL of the graph data the real module and action - 'module' => $currentControllerName, - 'action' => $currentControllerAction, - ); - } - - /** - * Sets parameters to modify in the future generated URL - * - * @param array $array array('nameParameter' => $newValue, ...) - */ - public function setParametersToModify($array) - { - $this->parametersToModify = array_merge($this->parametersToModify, $array); - } - - /** - * @see Piwik_ViewDataTable::main() - * - */ - public function main() - { - if($this->mainAlreadyExecuted) - { - return; - } - $this->mainAlreadyExecuted = true; - - $view = new Piwik_View($this->dataTableTemplate); - $this->id = $this->getUniqIdTable(); - $view->graphType = $this->graphType; - - $this->parametersToModify['action'] = $this->currentControllerAction; - $url = Piwik_Url::getCurrentQueryStringWithParametersModified($this->parametersToModify); - $view->jsInvocationTag = $this->getFlashInvocationCode($url); - $view->urlData = $url; - - $view->formId = "formEmbed".$this->id; - $view->codeEmbed = $this->codeEmbed; - - $view->id = $this->id; - $view->method = $this->method; - $view->javascriptVariablesToSet = $this->getJavascriptVariablesToSet(); - $view->showFooter = $this->getShowFooter(); - $this->view = $view; - } - - protected function getFlashInvocationCode( $url = 'libs/open-flash-chart/data-files/nodata.txt', $use_swfobject = true ) - { - $width = $this->width; - $height = $this->height; - - $libPathInPiwik = 'libs/open-flash-chart/'; - $currentPath = Piwik_Url::getCurrentUrlWithoutFileName(); - $pathToLibraryOpenChart = $currentPath . $libPathInPiwik; - - $url = Piwik_Url::getCurrentUrlWithoutQueryString() . $url; - // escape the & and stuff: - $url = urlencode($url); - - $obj_id = $this->id . "Chart"; - $div_name = $this->id . "FlashContent"; - - $return = ''; - if( $use_swfobject ) - { - // Using library for auto-enabling Flash object on IE, disabled-Javascript proof - $return .= ' - <div id="'. $div_name .'"></div> - <script type="text/javascript"> - var so = new SWFObject("'.$pathToLibraryOpenChart.'open-flash-chart.swf", "'.$obj_id.'_swf", "'. $width . '", "' . $height . '", "9", "#FFFFFF"); - so.addVariable("data", "'. $url . '"); - so.addParam("allowScriptAccess", "sameDomain"); - so.write("'. $div_name .'"); - </script> - <noscript> - '; - } - $urlGraph = $pathToLibraryOpenChart."open-flash-chart.swf?data=" . $url; - - $this->codeEmbed .= "<div><object classid='clsid:d27cdb6e-ae6d-11cf-96b8-444553540000' codebase='http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0' width='" . $width . "' height='" . $height . "' id='". $obj_id ."' >". - "<param name='movie' value='".$urlGraph."' />". - "<param name='allowScriptAccess' value='sameDomain' /> ". - "<embed src='$urlGraph' allowScriptAccess='sameDomain' quality='high' bgcolor='#FFFFFF' width='". $width ."' height='". $height ."' name='open-flash-chart' type='application/x-shockwave-flash' id='". $obj_id ."' />". - "</object></div>"; - $return .= $this->codeEmbed; - - if ( $use_swfobject ) { - $return .= '</noscript>'; - } - - return $return; - } -} - diff --git a/modules/ViewDataTable/GenerateGraphHTML/ChartEvolution.php b/modules/ViewDataTable/GenerateGraphHTML/ChartEvolution.php deleted file mode 100644 index d1db503052..0000000000 --- a/modules/ViewDataTable/GenerateGraphHTML/ChartEvolution.php +++ /dev/null @@ -1,31 +0,0 @@ -<?php -require_once "ViewDataTable/GenerateGraphHTML.php"; -/** - * Generates HTML embed for the Evolution graph - * - * @package Piwik_ViewDataTable - * - */ -class Piwik_ViewDataTable_GenerateGraphHTML_ChartEvolution extends Piwik_ViewDataTable_GenerateGraphHTML -{ - function __construct() - { - $this->valueParameterViewDataTable = 'generateDataChartEvolution'; - $this->width='100%'; - $this->height=150; - // used for the CSS class to apply to the DIV containing the graph - $this->graphType = 'evolution'; - } - - function init($currentControllerName, - $currentControllerAction, - $moduleNameAndMethod ) - { - parent::init($currentControllerName, - $currentControllerAction, - $moduleNameAndMethod ); - - $this->setParametersToModify(array('date' => 'last30')); - $this->doNotShowFooter(); - } -}
\ No newline at end of file diff --git a/modules/ViewDataTable/GenerateGraphHTML/ChartPie.php b/modules/ViewDataTable/GenerateGraphHTML/ChartPie.php deleted file mode 100644 index 35d037c65b..0000000000 --- a/modules/ViewDataTable/GenerateGraphHTML/ChartPie.php +++ /dev/null @@ -1,15 +0,0 @@ -<?php -require_once "ViewDataTable/GenerateGraphHTML.php"; -/** - * Generates HTML embed for the Pie chart - * - * @package Piwik_ViewDataTable - * - */ -class Piwik_ViewDataTable_GenerateGraphHTML_ChartPie extends Piwik_ViewDataTable_GenerateGraphHTML -{ - function __construct() - { - $this->valueParameterViewDataTable = 'generateDataChartPie'; - } -}
\ No newline at end of file diff --git a/modules/ViewDataTable/GenerateGraphHTML/ChartVerticalBar.php b/modules/ViewDataTable/GenerateGraphHTML/ChartVerticalBar.php deleted file mode 100644 index c1e03fea78..0000000000 --- a/modules/ViewDataTable/GenerateGraphHTML/ChartVerticalBar.php +++ /dev/null @@ -1,16 +0,0 @@ -<?php -require_once "ViewDataTable/GenerateGraphHTML.php"; -/** - * - * Generates HTML embed for the vertical bar chart - * - * @package Piwik_ViewDataTable - * - */ -class Piwik_ViewDataTable_GenerateGraphHTML_ChartVerticalBar extends Piwik_ViewDataTable_GenerateGraphHTML -{ - function __construct() - { - $this->valueParameterViewDataTable = 'generateDataChartVerticalBar'; - } -}
\ No newline at end of file diff --git a/modules/ViewDataTable/Html.php b/modules/ViewDataTable/Html.php deleted file mode 100644 index 0aaa981d2a..0000000000 --- a/modules/ViewDataTable/Html.php +++ /dev/null @@ -1,274 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_ViewDataTable - */ - -/** - * - * Outputs an AJAX Table for a given DataTable. - * - * Reads the requested DataTable from the API. - * - * @package Piwik_ViewDataTable - * - */ -class Piwik_ViewDataTable_Html extends Piwik_ViewDataTable -{ - /** - * Array of columns names to display - * - * @var array - */ - protected $columnsToDisplay = array(); - - /** - * Array of columns names translations - * - * @var array - */ - protected $columnsTranslations = array(); - - /** - * PHP array conversion of the Piwik_DataTable - * - * @var array - */ - public $arrayDataTable; // phpArray - - /** - * @see Piwik_ViewDataTable::init() - */ - function init($currentControllerName, - $currentControllerAction, - $moduleNameAndMethod, - $actionToLoadTheSubTable = null ) - { - parent::init($currentControllerName, - $currentControllerAction, - $moduleNameAndMethod, - $actionToLoadTheSubTable); - $this->dataTableTemplate = 'CoreHome/templates/datatable.tpl'; - - $this->variablesDefault['enable_sort'] = true; - - // load general columns translations - $this->setColumnTranslation('nb_visits', Piwik_Translate('General_ColumnNbVisits')); - $this->setColumnTranslation('label', Piwik_Translate('General_ColumnLabel')); - $this->setColumnTranslation('nb_uniq_visitors', Piwik_Translate('General_ColumnNbUniqVisitors')); - } - - /** - * @see Piwik_ViewDataTable::main() - * - */ - public function main() - { - if($this->mainAlreadyExecuted) - { - return; - } - $this->mainAlreadyExecuted = true; - -// $i=0;while($i<1500000){ $j=$i*$i;$i++;} - - $this->loadDataTableFromAPI(); - - // We apply a filter to the DataTable, decoding the label column (useful for keywords for example) - $filter = new Piwik_DataTable_Filter_ColumnCallbackReplace( - $this->dataTable, - 'label', - 'urldecode' - ); - - - $view = new Piwik_View($this->dataTableTemplate); - - - // We get the PHP array converted from the DataTable - $phpArray = $this->getPHPArrayFromDataTable(); - - $view->arrayDataTable = $phpArray; - $view->method = $this->method; - - $columns = $this->getColumnsToDisplay($phpArray); - $view->dataTableColumns = $columns; - - $nbColumns = count($columns); - // case no data in the array we use the number of columns set to be displayed - if($nbColumns == 0) - { - $nbColumns = count($this->columnsToDisplay); - } - - $view->nbColumns = $nbColumns; - - $view->id = $this->getUniqIdTable(); - $view->javascriptVariablesToSet = $this->getJavascriptVariablesToSet(); - $view->showFooter = $this->getShowFooter(); - $this->view = $view; - } - - /** - * Returns friendly php array from the Piwik_DataTable - * @see Piwik_DataTable_Renderer_Php - * @return array - */ - protected function getPHPArrayFromDataTable() - { - $renderer = Piwik_DataTable_Renderer::factory('php'); - $renderer->setTable($this->dataTable); - $renderer->setSerialize( false ); - // we get the php array from the datatable - // but conserving the original datatable format, which means rows 'columns', 'metadata' and 'idsubdatatable' - $phpArray = $renderer->originalRender(); - return $phpArray; - } - - /** - * Sets the columns that will be displayed in the HTML output - * By default all columns are displayed ($columnsNames = array() will display all columns) - * - * @param array $columnsNames Array of column names eg. array('nb_visits','nb_hits') - */ - public function setColumnsToDisplay( $columnsNames) - { - $this->columnsToDisplay = $columnsNames; - } - - /** - * Sets translation string for given column - * - * @param string $columnName column name - * @param string $columnTranslation column name translation - */ - public function setColumnTranslation( $columnName, $columnTranslation ) - { - $this->columnsTranslations[$columnName] = $columnTranslation; - } - - /** - * Returns column translation if available, in other case given column name - * - * @param string $columnName column name - */ - public function getColumnTranslation( $columnName ) - { - if( isset($this->columnsTranslations[$columnName]) ) - { - return $this->columnsTranslations[$columnName]; - } - else - { - return $columnName; - } - } - - /** - * Sets columns translations array. - * - * @param array $columnsTranslations An associative array indexed by column names, eg. array('nb_visit'=>"Numer of visits") - */ - public function setColumnsTranslations( $columnsTranslations ) - { - $this->columnsTranslations = $columnsTranslations; - } - - /** - * Returns array( - * array('id' => 1, 'name' => 'nb_visits'), - * array('id' => 3, 'name' => 'nb_uniq_visitors'), - * - * @param array PHP array conversion of the data table - * @return array - */ - protected function getColumnsToDisplay($phpArray) - { - $dataTableColumns = array(); - if(count($phpArray) > 0) - { - // build column information - $id = 0; - foreach($phpArray[0]['columns'] as $columnName => $row) - { - if( $this->isColumnToDisplay( $id, $columnName) ) - { - $dataTableColumns[] = array('id' => $id, 'name' => $columnName, 'displayName' => $this->getColumnTranslation($columnName) ); - } - $id++; - } - } - return $dataTableColumns; - } - - /** - * Returns true if the given column (id = $idColumn or name = $nameColumn) is set to be displayed. - * - * @param int $idColumn - * @param string $nameColumn - * @return bool - */ - protected function isColumnToDisplay( $idColumn, $nameColumn ) - { - // we return true - // - we didn't set any column to display (means we display all the columns) - // - the column has been set as to display - if( count($this->columnsToDisplay) == 0 - || in_array($idColumn, $this->columnsToDisplay) - || in_array($nameColumn, $this->columnsToDisplay)) - { - return true; - } - return false; - } - - /** - * Sets the columns in the HTML table as not sortable (they are not clickable) - * - * @return void - */ - public function disableSort() - { - $this->variablesDefault['enable_sort'] = 'false'; - } - - /** - * Sets the search on a table to be recursive (also searches in subtables) - * Works only on Actions/Downloads/Outlinks tables. - * - * @return bool If the pattern for a recursive search was set in the URL - */ - public function setSearchRecursive() - { - $this->variablesDefault['search_recursive'] = true; - return $this->setRecursiveLoadDataTableIfSearchingForPattern(); - } - - /** - * Set the flag to load the datatable recursively so we can search on subtables as well - * - * @return bool if recursive search is enabled - */ - protected function setRecursiveLoadDataTableIfSearchingForPattern() - { - try{ - $requestValue = Piwik_Common::getRequestVar('filter_column_recursive'); - $requestValue = Piwik_Common::getRequestVar('filter_pattern_recursive'); - // if the 2 variables are set we are searching for something. - // we have to load all the children subtables in this case - - $this->recursiveDataTableLoad = true; - return true; - } - catch(Exception $e) { - $this->recursiveDataTableLoad = false; - return false; - } - } -} - diff --git a/modules/ViewDataTable/Sparkline.php b/modules/ViewDataTable/Sparkline.php deleted file mode 100644 index b66630669a..0000000000 --- a/modules/ViewDataTable/Sparkline.php +++ /dev/null @@ -1,67 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id: Html.php 404 2008-03-23 01:09:59Z matt $ - * - * @package Piwik_ViewDataTable - */ - - -require_once "Visualization/Sparkline.php"; - -/** - * Reads the requested DataTable from the API and prepare data for the Sparkline view. - * - * @package Piwik_ViewDataTable - * - */ -class Piwik_ViewDataTable_Sparkline extends Piwik_ViewDataTable -{ - - /** - * @see Piwik_ViewDataTable::init() - */ - function init($currentControllerName, - $currentControllerAction, - $moduleNameAndMethod ) - { - parent::init($currentControllerName, - $currentControllerAction, - $moduleNameAndMethod ); - } - - /** - * @see Piwik_ViewDataTable::main() - */ - public function main() - { - if($this->mainAlreadyExecuted) - { - return; - } - $this->mainAlreadyExecuted = true; - - // we load the data with the filters applied - $this->loadDataTableFromAPI(); - - $this->dataAvailable = $this->dataTable->getRowsCount() != 0; - - if(!$this->dataAvailable) - { - throw new Exception( "No data for this graph" ); - } - else - { - $data = $this->generateDataFromDataTableArray($this->dataTable); - - $graph = new Piwik_Visualization_Sparkline; - $graph->setData($data); - $graph->main(); -// var_dump($data);exit; - $this->view = $graph; - } - } -} diff --git a/modules/Visualization/Chart.php b/modules/Visualization/Chart.php deleted file mode 100644 index b5bdcbfe41..0000000000 --- a/modules/Visualization/Chart.php +++ /dev/null @@ -1,88 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_Visualization - */ - -require_once "Visualization/OpenFlashChart.php"; - -/** - * Generates the data in the Open Flash Chart format, from the given data. - * Uses Open flash chart PHP library @see Piwik_Visualization_OpenFlashChart - * - * @package Piwik_Visualization - */ -abstract class Piwik_Visualization_Chart extends Piwik_Visualization_OpenFlashChart -{ - - protected $dataGraph = array(); - - function setData($data) - { - $this->dataGraph = $data; - } - - function getCount() - { - return count($this->dataGraph); - } - - function customizeGraph() - { - $this->set_num_decimals ( 0 ); - $this->set_is_decimal_separator_comma( false ); - $this->set_is_thousand_separator_disabled( true ); - $this->y_axis_colour = '#ffffff'; - $this->x_axis_colour = '#596171'; - $this->x_grid_colour = $this->y_grid_colour = '#E0E1E4'; - - // approx 5 x labels on the graph - $steps = ceil($this->getCount() / 5); - $steps = $steps + $steps % 2; // make sure modulo 2 - - $this->set_x_label_style( 10, $this->x_axis_colour, 0, $steps, $this->x_grid_colour ); - $this->set_x_axis_steps( $steps / 2 ); - - - $stepsY = ceil($this->getCount() / 4); - $this->y_label_steps( $stepsY / 3 ); - $this->y_label_steps( 4 ); - - $this->bg_colour = '#ffffff'; - $this->set_inner_background('#ffffff'); - - $this->set_tool_tip( '#x_label# <br>#val# #key# ' ); - } - - function prepareData() - { - $label = $data = array(); - $max = 0; - foreach($this->dataGraph as $row) - { - $label[] = $row['label']; - $data[] = $row['value']; - - if($row['value'] > $max) - { - $max = $row['value']; - } - } - $this->arrayData = $data; - $this->arrayLabel = $label; - - $this->arrayLabel = str_replace(","," -",$this->arrayLabel); - - $this->maxData = $max; - if($this->maxData > 10) - { - $this->maxData = $max + 10 - $max % 10; - } - } - -}
\ No newline at end of file diff --git a/modules/Visualization/ChartEvolution.php b/modules/Visualization/ChartEvolution.php deleted file mode 100644 index 066dbc9cff..0000000000 --- a/modules/Visualization/ChartEvolution.php +++ /dev/null @@ -1,58 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id: ChartVerticalBar.php 168 2008-01-14 05:26:43Z matt $ - * - * @package Piwik_Visualization - */ - -require_once "Visualization/Chart.php"; - -/** - * Customize the Evolution chart style for the flash graph - * - * @package Piwik_Visualization - * - */ -class Piwik_Visualization_ChartEvolution extends Piwik_Visualization_Chart -{ - function customizeGraph() - { - parent::customizeGraph(); - $this->prepareData(); - $this->set_y_max( $this->maxData ); - - $line_1 = new line_hollow( 1, 3, '0x3357A0' ); - $line_1->key( 'visits', 10 ); - - $i = 0; - foreach($this->arrayData as $value) - { - // hack until we have proper date handling - $spacePosition = strpos($this->arrayLabel[$i],' '); - if($spacePosition === false) - { - $spacePosition = strlen($this->arrayLabel[$i]); - } - - // generate the link on the dot, to the given day' statistics - $link = Piwik_Url::getCurrentScriptName() - . Piwik_Url::getCurrentQueryStringWithParametersModified( array( - 'date' => substr($this->arrayLabel[$i],0,$spacePosition), - 'module' => 'CoreHome', - 'action' => 'index', - 'viewDataTable' => null// we reset the viewDataTable parameter (useless in the link) - )); - - $line_1->add_link($value, $link ); - $i++; - } - $this->data_sets[] = $line_1; - - $this->set_x_labels( $this->arrayLabel ); - $this->area_hollow( 1, 3, 4,'0x3357A0', ' visits', 10 ); - } -}
\ No newline at end of file diff --git a/modules/Visualization/ChartPie.php b/modules/Visualization/ChartPie.php deleted file mode 100644 index 80c6532541..0000000000 --- a/modules/Visualization/ChartPie.php +++ /dev/null @@ -1,41 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_Visualization - */ -require_once "Visualization/Chart.php"; - -/** - * - * Customize the Pie chart style for the flash graph - * - * @package Piwik_Visualization - */ -class Piwik_Visualization_ChartPie extends Piwik_Visualization_Chart -{ - function customizeGraph() - { - parent::customizeGraph(); - - $this->prepareData(); - - for($i = 0, $cnt = count($this->arrayLabel); $i < $cnt; $i++) - { - $label = $this->arrayLabel[$i]; - $this->arrayLabel[$i] = (strlen($label) > 20 ? substr($label, 0, 20).'...' : $label); - } - $this->set_x_label_style( 12, $this->x_axis_colour, 0, 2, $this->bg_colour ); - $this->pie(60,'#505050','{font-size: 12px; color: #142448}', true); - $this->pie_values( $this->arrayData, $this->arrayLabel ); - $this->pie_slice_colours( array('#3C5A69','#679BB5','#695A3C','#B58E67','#969696') ); - - $this->set_tool_tip( '#x_label# <br>#val# ' ); - - } - -}
\ No newline at end of file diff --git a/modules/Visualization/ChartVerticalBar.php b/modules/Visualization/ChartVerticalBar.php deleted file mode 100644 index 8957ea2daa..0000000000 --- a/modules/Visualization/ChartVerticalBar.php +++ /dev/null @@ -1,38 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_Visualization - */ - -require_once "Visualization/Chart.php"; - -/** - * - * Customize the Vertical bar chart style for the flash graph - * - * @package Piwik_Visualization - * - */ -class Piwik_Visualization_ChartVerticalBar extends Piwik_Visualization_Chart -{ - protected $limit = 10; - - function customizeGraph() - { - parent::customizeGraph(); - $this->prepareData(); - $this->set_data( $this->arrayData ); - $this->set_x_labels( $this->arrayLabel ); - $this->set_x_label_style( 12, $this->x_axis_colour, 0, 2, $this->bg_colour ); - $this->set_x_axis_steps( 2 ); - $this->set_y_max( $this->maxData ); - $this->y_label_steps( 2 ); - $this->bar_filled( 50, '#3B5AA9', '#063E7E', 'visits', 10 ); - } - -}
\ No newline at end of file diff --git a/modules/Visualization/Cloud.php b/modules/Visualization/Cloud.php deleted file mode 100644 index 2a8924f5db..0000000000 --- a/modules/Visualization/Cloud.php +++ /dev/null @@ -1,169 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_Visualization - */ - - -/** - * Generates a tag cloud from a given data array. - * The generated tag cloud can be in PHP format, or in HTML. - * - * Inspired from Derek Harvey (www.derekharvey.co.uk) - * - * @package Piwik_Visualization - */ -class Piwik_Visualization_Cloud -{ - protected $wordsArray = array(); - - public $truncatingLimit = 30; - - /** - * @param array array( word => 10, word2 => 50, word3 => 1) - */ - function __construct($words = false) - { - if ($words !== false && is_array($words)) - { - foreach ($words as $word => $value) - { - $this->addWord($word, $value); - } - } - } - - /* - * Assign word to array - * - * @param string $word - * @return string - */ - function addWord($word, $value = 1) - { - // $word = strtolower($word); - if (isset($this->wordsArray[$word])) - { - $this->wordsArray[$word] += $value; - } - else - { - $this->wordsArray[$word] = $value; - } - } - - /* - * Shuffle associated names in array - */ - function shuffleCloud() - { - $keys = array_keys($this->wordsArray); - - shuffle($keys); - - if (count($keys) && is_array($keys)) - { - $tmpArray = $this->wordsArray; - $this->wordsArray = array(); - foreach ($keys as $key => $value) - $this->wordsArray[$value] = $tmpArray[$value]; - } - } - - /* - * Calculate size of words array - */ - - function getCloudSize() - { - return array_sum($this->wordsArray); - } - - /* - * Get the class range using a percentage - * - * @returns int $class - */ - function getClassFromPercent($percent) - { - $mapping = array( - 95, - 70, - 50, - 30, - 15, - 5, - 0 - ); - foreach($mapping as $key => $value) - { - if($percent >= $value) - { - return $key; - } - } - } - - /* - * Create the HTML code for each word and apply font size. - * - * @returns string $spans - */ - - function render($returnType = "html") - { - $this->shuffleCloud(); - - if($returnType == "html") - { - $return = ''; - } - else - { - $return = array(); - } - - if (count($this->wordsArray) > 0) - { - $this->max = max($this->wordsArray); - - $return = ($returnType == "html" ? "" : ($returnType == "array" ? array() : "")); - foreach ($this->wordsArray as $word => $popularity) - { - - // truncating the word - $wordTruncated = $word; - if(strlen($word) > $this->truncatingLimit) - { - $wordTruncated = substr($word, 0, $this->truncatingLimit - 3).'...'; - } - - // computing the percentage - $percent = ($popularity / $this->max) * 100; - - // and the CSS style value - $sizeRange = $this->getClassFromPercent($percent); - - if ($returnType == "array") - { - $return[$word]['word'] = $word; - $return[$word]['wordTruncated'] = $wordTruncated; - $return[$word]['size'] = $sizeRange; - $return[$word]['percent'] = $percent; - } - else if ($returnType == "html") - { - $return .= "\n<span title='".$word."' class='word size{$sizeRange}'> {$wordTruncated} </span>"; - } - // print( $word ."=".$percent."<br>"); - } - } - return $return; - } -} - diff --git a/modules/Visualization/OpenFlashChart.php b/modules/Visualization/OpenFlashChart.php deleted file mode 100644 index 41255e6373..0000000000 --- a/modules/Visualization/OpenFlashChart.php +++ /dev/null @@ -1,1647 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id$ - * - * @package Piwik_Visualization - * @subpackage OFC - */ - -require_once "iView.php"; - - -/** - * Original class provided by Open Flash Chart - * - * @package Piwik_Visualization - */ -abstract class Piwik_Visualization_OpenFlashChart implements Piwik_iView -{ - function __construct() - { - - $this->data_sets = array(); - - - $this->data = array(); - $this->links = array(); - $this->width = 250; - $this->height = 200; - $this->js_path = 'js/'; - $this->swf_path = ''; - $this->x_labels = array(); - $this->y_min = ''; - $this->y_max = ''; - $this->x_min = ''; - $this->x_max = ''; - $this->y_steps = ''; - $this->title = ''; - $this->title_style = ''; - $this->occurence = 0; - - $this->x_offset = ''; - - $this->x_tick_size = -1; - - $this->y2_max = ''; - $this->y2_min = ''; - - // GRID styles: - $this->x_axis_colour = ''; - $this->x_axis_3d = ''; - $this->x_grid_colour = ''; - $this->x_axis_steps = 1; - $this->y_axis_colour = ''; - $this->y_grid_colour = ''; - $this->y2_axis_colour = ''; - - // AXIS LABEL styles: - $this->x_label_style = ''; - $this->y_label_style = ''; - $this->y_label_style_right = ''; - - - // AXIS LEGEND styles: - $this->x_legend = ''; - $this->x_legend_size = 20; - $this->x_legend_colour = '#000000'; - - $this->y_legend = ''; - $this->y_legend_right = ''; - //$this->y_legend_size = 20; - //$this->y_legend_colour = '#000000'; - - $this->lines = array(); - $this->line_default['type'] = 'line'; - $this->line_default['values'] = '3,#87421F'; - $this->js_line_default = 'so.addVariable("line","3,#87421F");'; - - $this->bg_colour = ''; - $this->bg_image = ''; - - $this->inner_bg_colour = ''; - $this->inner_bg_colour_2 = ''; - $this->inner_bg_angle = ''; - - // PIE chart ------------ - $this->pie = ''; - $this->pie_values = ''; - $this->pie_colours = ''; - $this->pie_labels = ''; - - $this->tool_tip = ''; - - // which data lines are attached to the - // right Y axis? - $this->y2_lines = array(); - - // Number formatting: - $this->y_format=''; - $this->num_decimals=''; - $this->is_fixed_num_decimals_forced=''; - $this->is_decimal_separator_comma=''; - $this->is_thousand_separator_disabled=''; - - $this->output_type = ''; - - // - // set some default value incase the user forgets - // to set them, so at least they see *something* - // even is it is only the axis and some ticks - // - $this->set_y_min( 0 ); - $this->set_y_max( 20 ); - $this->set_x_axis_steps( 1 ); - $this->y_label_steps( 5 ); - } - - /** - * Set the unique_id to use for the flash object id. - */ - function set_unique_id() - { - $this->unique_id = uniqid(rand(), true); - } - - /** - * Get the flash object ID for the last rendered object. - */ - function get_unique_id() - { - return ($this->unique_id); - } - - /** - * Set the base path for the swfobject.js - * - * @param base_path a string argument. - * The path to the swfobject.js file - */ - function set_js_path($path) - { - $this->js_path = $path; - } - - /** - * Set the base path for the open-flash-chart.swf - * - * @param path a string argument. - * The path to the open-flash-chart.swf file - */ - function set_swf_path($path) - { - $this->swf_path = $path; - } - - /** - * Set the type of output data. - * - * @param type a string argument. - * The type of data. Currently only type is js, or nothing. - */ - function set_output_type($type) - { - $this->output_type = $type; - } - - /** - * returns the next line label for multiple lines. - */ - function next_line() - { - $line_num = ''; - if( count( $this->lines ) > 0 ) - $line_num = '_'. (count( $this->lines )+1); - - return $line_num; - } - - // escape commas (,) - static function esc( $text ) - { - // we replace the comma so it is not URL escaped - // if it is, flash just thinks it is a comma - // which is no good if we are splitting the - // string on commas. - $tmp = str_replace( ',', '#comma#', $text ); - //$tmp = utf8_encode( $tmp ); - // now we urlescape all dodgy characters (like & % $ etc..) - return urlencode( $tmp ); - } - - /** - * Format the text to the type of output. - */ - function format_output($function,$values) - { - if($this->output_type == 'js') - { - $tmp = 'so.addVariable("'. $function .'","'. $values . '");'; - } - else - { - $tmp = '&'. $function .'='. $values .'&'; - } - - return $tmp; - } - - /** - * Set the text and style of the title. - * - * @param title a string argument. - * The text of the title. - * @param style a string. - * CSS styling of the title. - */ - function set_title( $title, $style='' ) - { - $this->title = $this->esc( $title ); - if( strlen( $style ) > 0 ) - $this->title_style = $style; - } - - /** - * Set the width of the chart. - * - * @param width an int argument. - * The width of the chart frame. - */ - function set_width( $width ) - { - $this->width = $width; - } - - /** - * Set the height of the chart. - * - * @param height an int argument. - * The height of the chart frame. - */ - function set_height( $height ) - { - $this->height = $height; - } - - /** - * Set the base path of the swfobject. - * - * @param base a string argument. - * The base path of the swfobject. - */ - function set_base( $base='js/' ) - { - $this->base = $base; - } - - // Number formatting: - function set_y_format( $val ) - { - $this->y_format = $val; - } - - function set_num_decimals( $val ) - { - $this->num_decimals = $val; - } - - function set_is_fixed_num_decimals_forced( $val ) - { - $this->is_fixed_num_decimals_forced = $val?'true':'false'; - } - - function set_is_decimal_separator_comma( $val ) - { - $this->is_decimal_separator_comma = $val?'true':'false'; - } - - function set_is_thousand_separator_disabled( $val ) - { - $this->is_thousand_separator_disabled = $val?'true':'false'; - } - - /** - * Set the data for the chart - * @param a an array argument. - * An array of the data to add to the chart. - */ - function set_data( $a ) - { - $this->data[] = implode(',',$a); - } - - // UGH, these evil functions are making me fell ill - function set_links( $links ) - { - // TO DO escape commas: - $this->links[] = implode(',',$links); - } - - // $val is a boolean - function set_x_offset( $val ) - { - $this->x_offset = $val?'true':'false'; - } - - /** - * Set the tooltip to be displayed on each chart item.\n - * \n - * Replaceable tokens that can be used in the string include: \n - * #val# - The actual value of whatever the mouse is over. \n - * #key# - The key string. \n - * \<br> - New line. \n - * #x_label# - The X label string. \n - * #x_legend# - The X axis legend text. \n - * Default string is: "#x_label#<br>#val#" \n - * - * @param tip a string argument. - * A formatted string to show as the tooltip. - */ - function set_tool_tip( $tip ) - { - $this->tool_tip = $this->esc( $tip ); - } - - /** - * Set the x axis labels - * - * @param a an array argument. - * An array of the x axis labels. - */ - function set_x_labels( $a ) - { - $tmp = array(); - foreach( $a as $item ) - $tmp[] = $this->esc( $item ); - $this->x_labels = $tmp; - } - - /** - * Set the look and feel of the x axis labels - * - * @param font_size an int argument. - * The font size. - * @param colour a string argument. - * The hex colour value. - * @param orientation an int argument. - * The orientation of the x-axis text. - * 0 - Horizontal - * 1 - Vertical - * 2 - 45 degrees - * @param step an int argument. - * Show the label on every $step label. - * @param grid_colour a string argument. - */ - function set_x_label_style( $size, $colour='', $orientation=0, $step=-1, $grid_colour='' ) - { - $this->x_label_style = $size; - - if( strlen( $colour ) > 0 ) - $this->x_label_style .= ','. $colour; - - if( $orientation > -1 ) - $this->x_label_style .= ','. $orientation; - - if( $step > 0 ) - $this->x_label_style .= ','. $step; - - if( strlen( $grid_colour ) > 0 ) - $this->x_label_style .= ','. $grid_colour; - } - - /** - * Set the background colour. - * @param colour a string argument. - * The hex colour value. - */ - function set_bg_colour( $colour ) - { - $this->bg_colour = $colour; - } - - /** - * Set a background image. - * @param url a string argument. - * The location of the image. - * @param x a string argument. - * The x location of the image. 'Right', 'Left', 'Center' - * @param y a string argument. - * The y location of the image. 'Top', 'Bottom', 'Middle' - */ - function set_bg_image( $url, $x='center', $y='center' ) - { - $this->bg_image = $url; - $this->bg_image_x = $x; - $this->bg_image_y = $y; - } - - /** - * Attach a set of data (a line, area or bar chart) to the right Y axis. - * @param data_number an int argument. - * The numbered order the data was attached using set_data. - */ - function attach_to_y_right_axis( $data_number ) - { - $this->y2_lines[] = $data_number; - } - - /** - * Set the background colour of the grid portion of the chart. - * @param col a string argument. - * The hex colour value of the background. - * @param col2 a string argument. - * The hex colour value of the second colour if you want a gradient. - * @param angle an int argument. - * The angle in degrees to make the gradient. - */ - function set_inner_background( $col, $col2='', $angle=-1 ) - { - $this->inner_bg_colour = $col; - - if( strlen($col2) > 0 ) - $this->inner_bg_colour_2 = $col2; - - if( $angle != -1 ) - $this->inner_bg_angle = $angle; - } - - /** - * Internal function to build the y label style for y and y2 - */ - function _set_y_label_style( $size, $colour ) - { - $tmp = $size; - - if( strlen( $colour ) > 0 ) - $tmp .= ','. $colour; - return $tmp; - } - - /** - * Set the look and feel of the y axis labels - * - * @param font_size an int argument. - * The font size. - * @param colour a string argument. - * The hex colour value. - */ - function set_y_label_style( $size, $colour='' ) - { - $this->y_label_style = $this->_set_y_label_style( $size, $colour ); - } - - /** - * Set the look and feel of the right y axis labels - * - * @param font_size an int argument. - * The font size. - * @param colour a string argument. - * The hex colour value. - */ - function set_y_right_label_style( $size, $colour='' ) - { - $this->y_label_style_right = $this->_set_y_label_style( $size, $colour ); - } - - function set_x_max( $max ) - { - $this->x_max = floatval( $max ); - } - - function set_x_min( $min ) - { - $this->x_min = floatval( $min ); - } - - /** - * Set the maximum value of the y axis. - * - * @param max an float argument. - * The maximum value. - */ - function set_y_max( $max ) - { - $this->y_max = floatval( $max ); - } - - /** - * Set the minimum value of the y axis. - * - * @param min an float argument. - * The minimum value. - */ - function set_y_min( $min ) - { - $this->y_min = floatval( $min ); - } - - /** - * Set the maximum value of the right y axis. - * - * @param max an float argument. - * The maximum value. - */ - function set_y_right_max( $max ) - { - $this->y2_max = floatval($max); - } - - /** - * Set the minimum value of the right y axis. - * - * @param min an float argument. - * The minimum value. - */ - function set_y_right_min( $min ) - { - $this->y2_min = floatval($min); - } - - /** - * Show the y label on every $step label. - * - * @param val an int argument. - * Show the label on every $step label. - */ - function y_label_steps( $val ) - { - $this->y_steps = intval( $val ); - } - - function title( $title, $style='' ) - { - $this->title = $this->esc( $title ); - if( strlen( $style ) > 0 ) - $this->title_style = $style; - } - - /** - * Set the parameters of the x legend. - * - * @param text a string argument. - * The text of the x legend. - * @param font_size an int argument. - * The font size of the x legend text. - * @param colour a string argument - * The hex value of the font colour. - */ - function set_x_legend( $text, $size=-1, $colour='' ) - { - $this->x_legend = $this->esc( $text ); - if( $size > -1 ) - $this->x_legend_size = $size; - - if( strlen( $colour )>0 ) - $this->x_legend_colour = $colour; - } - - /** - * Set the size of the x label ticks. - * - * @param size an int argument. - * The size of the ticks in pixels. - */ - function set_x_tick_size( $size ) - { - if( $size > 0 ) - $this->x_tick_size = $size; - } - - /** - * Set how often you would like to show a tick on the x axis. - * - * @param steps an int argument. - * Show a tick ever $steps. - */ - function set_x_axis_steps( $steps ) - { - if ( $steps > 0 ) - $this->x_axis_steps = $steps; - } - - /** - * Set the depth in pixels of the 3D X axis slab. - * - * @param size an int argument. - * The depth in pixels of the 3D X axis. - */ - function set_x_axis_3d( $size ) - { - if( $size > 0 ) - $this->x_axis_3d = intval($size); - } - - /** - * The private method of building the y legend output. - */ - function _set_y_legend( $text, $size, $colour ) - { - $tmp = $text; - - if( $size > -1 ) - $tmp .= ','. $size; - - if( strlen( $colour )>0 ) - $tmp .= ','. $colour; - - return $tmp; - } - - /** - * Set the parameters of the y legend. - * - * @param text a string argument. - * The text of the y legend. - * @param font_size an int argument. - * The font size of the y legend text. - * @param colour a string argument - * The hex colour value of the font colour. - */ - function set_y_legend( $text, $size=-1, $colour='' ) - { - $this->y_legend = $this->_set_y_legend( $text, $size, $colour ); - } - - /** - * Set the parameters of the right y legend. - * - * @param text a string argument. - * The text of the right y legend. - * @param font_size an int argument. - * The font size of the right y legend text. - * @param colour a string argument - * The hex value of the font colour. - */ - function set_y_right_legend( $text, $size=-1, $colour='' ) - { - $this->y_legend_right = $this->_set_y_legend( $text, $size, $colour ); - } - - /** - * Set the colour of the x axis line and grid. - * - * @param axis a string argument. - * The hex colour value of the x axis line. - * @param grid a string argument. - * The hex colour value of the x axis grid. - */ - function x_axis_colour( $axis, $grid='' ) - { - $this->x_axis_colour = $axis; - $this->x_grid_colour = $grid; - } - - /** - * Set the colour of the y axis line and grid. - * - * @param axis a string argument. - * The hex colour value of the y axis line. - * @param grid a string argument. - * The hex colour value of the y axis grid. - */ - function y_axis_colour( $axis, $grid='' ) - { - $this->y_axis_colour = $axis; - - if( strlen( $grid ) > 0 ) - $this->y_grid_colour = $grid; - } - - /** - * Set the colour of the right y axis line. - * - * @param colour a string argument. - * The hex colour value of the right y axis line. - */ - function y_right_axis_colour( $colour ) - { - $this->y2_axis_colour = $colour; - } - - /** - * Draw a line without markers on values. - * - * @param width an int argument. - * The width of the line in pixels. - * @param colour a string argument. - * The hex colour value of the line. - * @param text a string argument. - * The label of the line. - * @param font_size an int argument. - * Font size of the label - * @param circles an int argument - * Need to find out. - */ - function line( $width, $colour='', $text='', $size=-1, $circles=-1 ) - { - $type = 'line'. $this->next_line(); - - $description = ''; - if( $width > 0 ) - { - $description .= $width; - $description .= ','. $colour; - } - - if( strlen( $text ) > 0 ) - { - $description.= ','. $text; - $description .= ','. $size; - } - - if( $circles > 0 ) - $description .= ','. $circles; - - $this->lines[$type] = $description; - } - - /** - * Draw a line with solid dot markers on values. - * - * @param width an int argument. - * The width of the line in pixels. - * @param dot_size an int argument. - * Size in pixels of the dot. - * @param colour a string argument. - * The hex colour value of the line. - * @param text a string argument. - * The label of the line. - * @param font_size an int argument. - * Font size of the label. - */ - function line_dot( $width, $dot_size, $colour, $text='', $font_size='' ) - { - $type = 'line_dot'. $this->next_line(); - - $description = "$width,$colour,$text"; - - if( strlen( $font_size ) > 0 ) - $description .= ",$font_size,$dot_size"; - - $this->lines[$type] = $description; - } - - /** - * Draw a line with hollow dot markers on values. - * - * @param width an int argument. - * The width of the line in pixels. - * @param dot_size an int argument. - * Size in pixels of the dot. - * @param colour a string argument. - * The hex colour value of the line. - * @param text a string argument. - * The label of the line. - * @param font_size an int argument. - * Font size of the label. - */ - function line_hollow( $width, $dot_size, $colour, $text='', $font_size='' ) - { - $type = 'line_hollow'. $this->next_line(); - - $description = "$width,$colour,$text"; - - if( strlen( $font_size ) > 0 ) - $description .= ",$font_size,$dot_size"; - - $this->lines[$type] = $description; - } - - /** - * Draw an area chart. - * - * @param width an int argument. - * The width of the line in pixels. - * @param dot_size an int argument. - * Size in pixels of the dot. - * @param colour a string argument. - * The hex colour value of the line. - * @param alpha an int argument. - * The percentage of transparency of the fill colour. - * @param text a string argument. - * The label of the line. - * @param font_size an int argument. - * Font size of the label. - * @param fill_colour a string argument. - * The hex colour value of the fill colour. - */ - function area_hollow( $width, $dot_size, $colour, $alpha, $text='', $font_size='', $fill_colour='' ) - { - $type = 'area_hollow'. $this->next_line(); - - $description = "$width,$dot_size,$colour,$alpha"; - - if( strlen( $text ) > 0 ) - $description .= ",$text,$font_size"; - - if( strlen( $fill_colour ) > 0 ) - $description .= ','. $fill_colour; - - $this->lines[$type] = $description; - } - - /** - * Draw a bar chart. - * - * @param alpha an int argument. - * The percentage of transparency of the bar colour. - * @param colour a string argument. - * The hex colour value of the line. - * @param text a string argument. - * The label of the line. - * @param font_size an int argument. - * Font size of the label. - */ - function bar( $alpha, $colour='', $text='', $size=-1 ) - { - $type = 'bar'. $this->next_line(); - - $description = $alpha .','. $colour .','. $text .','. $size; - - $this->lines[$type] = $description; - } - - /** - * Draw a bar chart with an outline. - * - * @param alpha an int argument. - * The percentage of transparency of the bar colour. - * @param colour a string argument. - * The hex colour value of the line. - * @param colour_outline a strng argument. - * The hex colour value of the outline. - * @param text a string argument. - * The label of the line. - * @param font_size an int argument. - * Font size of the label. - */ - function bar_filled( $alpha, $colour, $colour_outline, $text='', $size=-1 ) - { - $type = 'filled_bar'. $this->next_line(); - - $description = "$alpha,$colour,$colour_outline,$text,$size"; - - $this->lines[$type] = $description; - } - - function bar_sketch( $alpha, $offset, $colour, $colour_outline, $text='', $size=-1 ) - { - $type = 'bar_sketch'. $this->next_line(); - - $description = "$alpha,$offset,$colour,$colour_outline,$text,$size"; - - $this->lines[$type] = $description; - } - - /** - * Draw a 3D bar chart. - * - * @param alpha an int argument. - * The percentage of transparency of the bar colour. - * @param colour a string argument. - * The hex colour value of the line. - * @param text a string argument. - * The label of the line. - * @param font_size an int argument. - * Font size of the label. - */ - function bar_3D( $alpha, $colour='', $text='', $size=-1 ) - { - $type = 'bar_3d'. $this->next_line(); - - $description = $alpha .','. $colour .','. $text .','. $size; - - $this->lines[$type] = $description; - } - - /** - * Draw a 3D bar chart that looks like glass. - * - * @param alpha an int argument. - * The percentage of transparency of the bar colour. - * @param colour a string argument. - * The hex colour value of the line. - * @param outline_colour a string argument. - * The hex colour value of the outline. - * @param text a string argument. - * The label of the line. - * @param font_size an int argument. - * Font size of the label. - */ - function bar_glass( $alpha, $colour, $outline_colour, $text='', $size=-1 ) - { - $type = 'bar_glass'. $this->next_line(); - - $description = $alpha .','. $colour .','. $outline_colour .','. $text .','. $size; - - $this->lines[$type] = $description; - } - - /** - * Draw a faded bar chart. - * - * @param alpha an int argument. - * The percentage of transparency of the bar colour. - * @param colour a string argument. - * The hex colour value of the line. - * @param text a string argument. - * The label of the line. - * @param font_size an int argument. - * Font size of the label. - */ - function bar_fade( $alpha, $colour='', $text='', $size=-1 ) - { - $type = 'bar_fade'. $this->next_line(); - - $description = $alpha .','. $colour .','. $text .','. $size; - - $this->lines[$type] = $description; - } - - function candle( $data, $alpha, $line_width, $colour, $text='', $size=-1 ) - { - $type = 'candle'. $this->next_line(); - - $description = $alpha .','. $line_width .','. $colour .','. $text .','. $size; - - $this->lines[$type] = $description; - - $a = array(); - foreach( $data as $can ) - $a[] = $can->toString(); - - $this->data[] = implode(',',$a); - } - - function hlc( $data, $alpha, $line_width, $colour, $text='', $size=-1 ) - { - $type = 'hlc'. $this->next_line(); - - $description = $alpha .','. $line_width .','. $colour .','. $text .','. $size; - - $this->lines[$type] = $description; - - $a = array(); - foreach( $data as $can ) - $a[] = $can->toString(); - - $this->data[] = implode(',',$a); - } - - function scatter( $data, $line_width, $colour, $text='', $size=-1 ) - { - $type = 'scatter'. $this->next_line(); - - $description = $line_width .','. $colour .','. $text .','. $size; - - $this->lines[$type] = $description; - - $a = array(); - foreach( $data as $can ) - $a[] = $can->toString(); - - $this->data[] = implode(',',$a); - } - - - // - // Patch by, Jeremy Miller (14th Nov, 2007) - // - /** - * Draw a pie chart. - * - * @param alpha an int argument. - * The percentage of transparency of the pie colour. - * @param $style a string argument. - * CSS style string - * @param label_colour a string argument. - * The hex colour value of the label. - * @param gradient a boolean argument. - * Use a gradient true or false. - * @param border_size an int argument. - * Size of the border in pixels. - */ - function pie( $alpha, $line_colour, $style, $gradient = true, $border_size = false ) - { - $this->pie = $alpha.','.$line_colour.','.$style; - if( !$gradient ) - { - $this->pie .= ','.!$gradient; - } - if ($border_size) - { - if ($gradient === false) - { - $this->pie .= ','; - } - $this->pie .= ','.$border_size; - } - } - - /** - * Set the values of the pie chart. - * - * @param values an array argument. - * An array of the values for the pie chart. - * @param labels an array argument. - * An array of the labels for the pie pieces. - * @param links an array argument. - * An array of the links to the pie pieces. - */ - function pie_values( $values, $labels=array(), $links=array() ) - { - $this->pie_values = implode(',',$values); - $this->pie_labels = implode(',',$labels); - $this->pie_links = implode(",",$links); - } - - /** - * Set the pie slice colours. - * - * @param colours an array argument. - * The hex colour values of the pie pieces. - */ - function pie_slice_colours( $colours ) - { - $this->pie_colours = implode(',',$colours); - } - - - /** - * Render the output. - */ - function render() - { - $tmp = array(); - - //echo headers_sent() ?'yes':'no'; - if( !headers_sent() ) - header('content-type: text; charset: utf-8'); - - if($this->output_type == 'js') - { - $this->set_unique_id(); - - $tmp[] = '<div id="' . $this->unique_id . '"></div>'; - $tmp[] = '<script type="text/javascript" src="' . $this->js_path . 'swfobject.js"></script>'; - $tmp[] = '<script type="text/javascript">'; - $tmp[] = 'var so = new SWFObject("' . $this->swf_path . 'open-flash-chart.swf", "ofc", "'. $this->width . '", "' . $this->height . '", "9", "#FFFFFF");'; - $tmp[] = 'so.addVariable("variables","true");'; - } - - if( strlen( $this->title ) > 0 ) - { - $values = $this->title; - $values .= ','. $this->title_style; - $tmp[] = $this->format_output('title',$values); - } - - if( strlen( $this->x_legend ) > 0 ) - { - $values = $this->x_legend; - $values .= ','. $this->x_legend_size; - $values .= ','. $this->x_legend_colour; - $tmp[] = $this->format_output('x_legend',$values); - } - - if( strlen( $this->x_label_style ) > 0 ) - $tmp[] = $this->format_output('x_label_style',$this->x_label_style); - - if( $this->x_tick_size > 0 ) - $tmp[] = $this->format_output('x_ticks',$this->x_tick_size); - - if( $this->x_axis_steps > 0 ) - $tmp[] = $this->format_output('x_axis_steps',$this->x_axis_steps); - - if( strlen( $this->x_axis_3d ) > 0 ) - $tmp[] = $this->format_output('x_axis_3d',$this->x_axis_3d); - - if( strlen( $this->y_legend ) > 0 ) - $tmp[] = $this->format_output('y_legend',$this->y_legend); - - if( strlen( $this->y_legend_right ) > 0 ) - $tmp[] = $this->format_output('y2_legend',$this->y_legend_right); - - if( strlen( $this->y_label_style ) > 0 ) - $tmp[] = $this->format_output('y_label_style',$this->y_label_style); - - $values = '5,10,'. $this->y_steps; - $tmp[] = $this->format_output('y_ticks',$values); - - if( count( $this->lines ) == 0 && count($this->data_sets)==0 ) - { - $tmp[] = $this->format_output($this->line_default['type'],$this->line_default['values']); - } - else - { - foreach( $this->lines as $type=>$description ) - $tmp[] = $this->format_output($type,$description); - } - - $num = 1; - foreach( $this->data as $data ) - { - if( $num==1 ) - { - $tmp[] = $this->format_output( 'values', $data); - } - else - { - $tmp[] = $this->format_output('values_'. $num, $data); - } - - $num++; - } - - $num = 1; - foreach( $this->links as $link ) - { - if( $num==1 ) - { - $tmp[] = $this->format_output( 'links', $link); - } - else - { - $tmp[] = $this->format_output('links_'. $num, $link); - } - - $num++; - } - - if( count( $this->y2_lines ) > 0 ) - { - $tmp[] = $this->format_output('y2_lines',implode( ',', $this->y2_lines )); - // - // Should this be an option? I think so... - // - $tmp[] = $this->format_output('show_y2','true'); - } - - if( count( $this->x_labels ) > 0 ) - $tmp[] = $this->format_output('x_labels',implode(',',$this->x_labels)); - else - { - if( strlen($this->x_min) > 0 ) - $tmp[] = $this->format_output('x_min',$this->x_min); - - if( strlen($this->x_max) > 0 ) - $tmp[] = $this->format_output('x_max',$this->x_max); - } - - $tmp[] = $this->format_output('y_min',$this->y_min); - $tmp[] = $this->format_output('y_max',$this->y_max); - - if( strlen($this->y2_min) > 0 ) - $tmp[] = $this->format_output('y2_min',$this->y2_min); - - if( strlen($this->y2_max) > 0 ) - $tmp[] = $this->format_output('y2_max',$this->y2_max); - - if( strlen( $this->bg_colour ) > 0 ) - $tmp[] = $this->format_output('bg_colour',$this->bg_colour); - - if( strlen( $this->bg_image ) > 0 ) - { - $tmp[] = $this->format_output('bg_image',$this->bg_image); - $tmp[] = $this->format_output('bg_image_x',$this->bg_image_x); - $tmp[] = $this->format_output('bg_image_y',$this->bg_image_y); - } - - if( strlen( $this->x_axis_colour ) > 0 ) - { - $tmp[] = $this->format_output('x_axis_colour',$this->x_axis_colour); - $tmp[] = $this->format_output('x_grid_colour',$this->x_grid_colour); - } - - if( strlen( $this->y_axis_colour ) > 0 ) - $tmp[] = $this->format_output('y_axis_colour',$this->y_axis_colour); - - if( strlen( $this->y_grid_colour ) > 0 ) - $tmp[] = $this->format_output('y_grid_colour',$this->y_grid_colour); - - if( strlen( $this->y2_axis_colour ) > 0 ) - $tmp[] = $this->format_output('y2_axis_colour',$this->y2_axis_colour); - - if( strlen( $this->x_offset ) > 0 ) - $tmp[] = $this->format_output('x_offset',$this->x_offset); - - if( strlen( $this->inner_bg_colour ) > 0 ) - { - $values = $this->inner_bg_colour; - if( strlen( $this->inner_bg_colour_2 ) > 0 ) - { - $values .= ','. $this->inner_bg_colour_2; - $values .= ','. $this->inner_bg_angle; - } - $tmp[] = $this->format_output('inner_background',$values); - } - - if( strlen( $this->pie ) > 0 ) - { - $tmp[] = $this->format_output('pie',$this->pie); - $tmp[] = $this->format_output('values',$this->pie_values); - $tmp[] = $this->format_output('pie_labels',$this->pie_labels); - $tmp[] = $this->format_output('colours',$this->pie_colours); - $tmp[] = $this->format_output('links',$this->pie_links); - } - - if( strlen( $this->tool_tip ) > 0 ) - $tmp[] = $this->format_output('tool_tip',$this->tool_tip); - - - - if( strlen( $this->y_format ) > 0 ) - $tmp[] = $this->format_output('y_format',$this->y_format); - - if( strlen( $this->num_decimals ) > 0 ) - $tmp[] = $this->format_output('num_decimals',$this->num_decimals); - - if( strlen( $this->is_fixed_num_decimals_forced ) > 0 ) - $tmp[] = $this->format_output('is_fixed_num_decimals_forced',$this->is_fixed_num_decimals_forced); - - if( strlen( $this->is_decimal_separator_comma ) > 0 ) - $tmp[] = $this->format_output('is_decimal_separator_comma',$this->is_decimal_separator_comma); - - if( strlen( $this->is_thousand_separator_disabled ) > 0 ) - $tmp[] = $this->format_output('is_thousand_separator_disabled',$this->is_thousand_separator_disabled); - - - $count = 1; - foreach( $this->data_sets as $set ) - { - $tmp[] = $set->toString( $this->output_type, $count>1?'_'.$count:'' ); - $count++; - } - - if($this->output_type == 'js') - { - $tmp[] = 'so.write("' . $this->unique_id . '");'; - $tmp[] = '</script>'; - } - - return implode("\r\n",$tmp); - } -} - -class line -{ - var $line_width; - var $colour; - var $_key; - var $key; - var $key_size; - // hold the data - var $data; - // extra tool tip info: - var $tips; - - function line( $line_width, $colour ) - { - $this->var = 'line'; - - $this->line_width = $line_width; - $this->colour = $colour; - $this->data = array(); - $this->links = array(); - $this->tips = array(); - $this->_key = false; - } - - - function key( $key, $size ) - { - $this->_key = true; - $this->key = graph::esc( $key ); - $this->key_size = $size; - } - - function add( $data ) - { - $this->data[] = $data; - } - - function add_link( $data, $link ) - { - $this->data[] = $data; - $this->links[] = graph::esc( $link ); - } - - function add_data_tip( $data, $tip ) - { - $this->data[] = $data; - $this->tips[] = graph::esc( $tip ); - } - - function add_data_link_tip( $data, $link, $tip ) - { - $this->data[] = $data; - $this->links[] = graph::esc( $link ); - $this->tips[] = graph::esc( $tip ); - } - - // return the variables for this chart - function _get_variable_list() - { - $values = array(); - $values[] = $this->line_width; - $values[] = $this->colour; - - if( $this->_key ) - { - $values[] = $this->key; - $values[] = $this->key_size; - } - - return $values; - } - - function toString( $output_type, $set_num ) - { - $values = implode( ',', $this->_get_variable_list() ); - - $tmp = array(); - - if( $output_type == 'js' ) - { - $tmp[] = 'so.addVariable("'. $this->var.$set_num .'","'. $values . '");'; - - $tmp[] = 'so.addVariable("values'. $set_num .'","'. implode( ',', $this->data ) .'");'; - - if( count( $this->links ) > 0 ) - $tmp[] = 'so.addVariable("links'. $set_num .'","'. implode( ',', $this->links ) .'");'; - - if( count( $this->tips ) > 0 ) - $tmp[] = 'so.addVariable("tool_tips_set'. $set_num .'","'. implode( ',', $this->tips ) .'");'; - - } - else - { - $tmp[] = '&'. $this->var. $set_num .'='. $values .'&'; - $tmp[] = '&values'. $set_num .'='. implode( ',', $this->data ) .'&'; - - if( count( $this->links ) > 0 ) - $tmp[] = '&links'. $set_num .'='. implode( ',', $this->links ) .'&'; - - if( count( $this->tips ) > 0 ) - $tmp[] = '&tool_tips_set'. $set_num .'='. implode( ',', $this->tips ) .'&'; - } - - return implode( "\r\n", $tmp ); - } -} - -class line_hollow extends line -{ - var $dot_size; - - function line_hollow( $line_width, $dot_size, $colour ) - { - parent::line( $line_width, $colour ); - $this->var = 'line_hollow'; - $this->dot_size = $dot_size; - } - - // return the variables for this chart - function _get_variable_list() - { - $values = array(); - $values[] = $this->line_width; - $values[] = $this->colour; - - if( $this->_key ) - { - $values[] = $this->key; - $values[] = $this->key_size; - } - else - { - $values[] = ''; - $values[] = ''; - } - $values[] = $this->dot_size; - - return $values; - } -} - -class line_dot extends line_hollow -{ - function line_dot( $line_width, $dot_size, $colour ) - { - parent::line_hollow( $line_width, $dot_size,$colour ); - $this->var = 'line_dot'; - } -} - -class bar -{ - var $colour; - var $alpha; - var $data; - var $links; - var $_key; - var $key; - var $key_size; - var $var; - // extra tool tip info: - var $tips; - - function bar( $alpha, $colour ) - { - $this->var = 'bar'; - - $this->alpha = $alpha; - $this->colour = $colour; - $this->data = array(); - $this->links = array(); - $this->tips = array(); - $this->_key = false; - } - - function key( $key, $size ) - { - $this->_key = true; - $this->key = graph::esc( $key ); - $this->key_size = $size; - } - - function add( $data ) - { - $this->data[] = $data; - } - - function add_link( $data, $link ) - { - $this->data[] = $data; - $this->links[] = graph::esc( $link ); - } - - function add_data_tip( $data, $tip ) - { - $this->data[] = $data; - $this->tips[] = graph::esc( $tip ); - } - - // return the variables for this - // bar chart - function _get_variable_list() - { - $values = array(); - $values[] = $this->alpha; - $values[] = $this->colour; - - if( $this->_key ) - { - $values[] = $this->key; - $values[] = $this->key_size; - } - - return $values; - } - - function toString( $output_type, $set_num ) - { - $values = implode( ',', $this->_get_variable_list() ); - - $tmp = array(); - - if( $output_type == 'js' ) - { - $tmp[] = 'so.addVariable("'. $this->var.$set_num .'","'. $values . '");'; - - $tmp[] = 'so.addVariable("values'. $set_num .'","'. implode( ',', $this->data ) .'");'; - - if( count( $this->links ) > 0 ) - $tmp[] = 'so.addVariable("links'. $set_num .'","'. implode( ',', $this->links ) .'");'; - - if( count( $this->tips ) > 0 ) - $tmp[] = 'so.addVariable("tool_tips_set'. $set_num .'","'. implode( ',', $this->tips ) .'");'; - - } - else - { - $tmp[] = '&'. $this->var. $set_num .'='. $values .'&'; - $tmp[] = '&values'. $set_num .'='. implode( ',', $this->data ) .'&'; - - if( count( $this->links ) > 0 ) - $tmp[] = '&links'. $set_num .'='. implode( ',', $this->links ) .'&'; - - if( count( $this->tips ) > 0 ) - $tmp[] = '&tool_tips_set'. $set_num .'='. implode( ',', $this->tips ) .'&'; - } - - return implode( "\r\n", $tmp ); - } - -} - -class bar_3d extends bar -{ - function bar_3d( $alpha, $colour ) - { - parent::bar( $alpha, $colour ); - $this->var = 'bar_3d'; - } -} - -class bar_fade extends bar -{ - function bar_fade( $alpha, $colour ) - { - parent::bar( $alpha, $colour ); - $this->var = 'bar_fade'; - } -} - -class bar_outline extends bar -{ - var $outline_colour; - - function bar_outline( $alpha, $colour, $outline_colour ) - { - parent::bar( $alpha, $colour ); - $this->var = 'filled_bar'; - $this->outline_colour = $outline_colour; - } - - // override the base method - function _get_variable_list() - { - $values = array(); - $values[] = $this->alpha; - $values[] = $this->colour; - $values[] = $this->outline_colour; - - if( $this->_key ) - { - $values[] = $this->key; - $values[] = $this->key_size; - } - - return $values; - } -} - -class bar_glass extends bar_outline -{ - function bar_glass( $alpha, $colour, $outline_colour ) - { - parent::bar_outline( $alpha, $colour, $outline_colour ); - $this->var = 'bar_glass'; - } -} - -// -// this has an outline colour and a 'jiggle' parameter -// called offset -// -class bar_sketch extends bar_outline -{ - var $offset; - - function bar_sketch( $alpha, $offset, $colour, $outline_colour ) - { - parent::bar_outline( $alpha, $colour, $outline_colour ); - $this->var = 'bar_sketch'; - $this->offset = $offset; - } - - // override the base method - function _get_variable_list() - { - $values = array(); - $values[] = $this->alpha; - $values[] = $this->offset; - $values[] = $this->colour; - $values[] = $this->outline_colour; - - if( $this->_key ) - { - $values[] = $this->key; - $values[] = $this->key_size; - } - - return $values; - } -} - -class candle -{ - var $out; - - function candle( $high, $open, $close, $low ) - { - $this->out = array(); - $this->out[] = $high; - $this->out[] = $open; - $this->out[] = $close; - $this->out[] = $low; - } - - function toString() - { - return '['. implode( ',', $this->out ) .']'; - } -} - -class hlc -{ - var $out; - - function hlc( $high, $low, $close ) - { - $this->out = array(); - $this->out[] = $high; - $this->out[] = $low; - $this->out[] = $close; - } - - function toString() - { - return '['. implode( ',', $this->out ) .']'; - } -} - -class point -{ - var $out; - - function point( $x, $y, $size_px ) - { - $this->out = array(); - $this->out[] = $x; - $this->out[] = $y; - $this->out[] = $size_px; - } - - function toString() - { - return '['. implode( ',', $this->out ) .']'; - } -} - -// PIWIK SPECIAL ALIAS HACK - when updating Open Flash Chart, leave this line unchanged -class graph extends Piwik_Visualization_OpenFlashChart {}
\ No newline at end of file diff --git a/modules/Visualization/Sparkline.php b/modules/Visualization/Sparkline.php deleted file mode 100644 index 65f529f338..0000000000 --- a/modules/Visualization/Sparkline.php +++ /dev/null @@ -1,89 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id: OpenFlashChart.php 386 2008-03-18 19:27:54Z julien $ - * - * @package Piwik_Visualization - */ - -require_once 'sparkline/lib/Sparkline_Line.php'; - - -/** - * Renders a sparkline image given a PHP data array. - * Using the Sparkline PHP Graphing Library sparkline.org - * - * @package Piwik_Visualization - */ -class Piwik_Visualization_Sparkline implements Piwik_iView -{ - /** - * Sets data. Must have format: array( array('value' => X),array('value' =>Y ), ...) - * - * @param array $data - */ - function setData($data) - { - $this->data = $data; - } - - - function main() - { - $data = $this->data; - $sparkline = new Sparkline_Line(); - - $sparkline->SetColor('lineColor', 22,44,74); // dark blue - $sparkline->SetColorHtml('red', '#FF7F7F'); - $sparkline->SetColorHtml('blue', '#55AAFF'); - $sparkline->SetColorHtml('green', '#75BF7C'); -// $sparkline->SetDebugLevel(DEBUG_NONE); -// $sparkline->SetDebugLevel(DEBUG_ERROR | DEBUG_WARNING | DEBUG_STATS | DEBUG_CALLS | DEBUG_DRAW, 'log.txt'); - - $data = array_reverse($data); - $min = $max= $last = null; - $i = 0; - - foreach($this->data as $row) - { - $value = $row['value']; - - $sparkline->SetData($i, $value); - if( null == $min || $value <= $min[1]) - { - $min = array($i, $value); - } - - if(null == $max || $value >= $max[1]) - { - $max = array($i, $value); - } - - $last = array($i, $value); - - $i++; - } - $sparkline->SetYMin(0); - $sparkline->SetPadding(2); // setpadding is additive - $sparkline->SetPadding(0,//13,//font height - 3, //4 * (strlen("$last[1]")), - 0, //imagefontheight(FONT_2), - 0); - $font = FONT_2; - $sparkline->SetFeaturePoint($min[0]-1,$min[1],'red', 5); - $sparkline->SetFeaturePoint($max[0]-1,$max[1], 'green', 5); - $sparkline->SetFeaturePoint($last[0]-1, $last[1], 'blue',5); - $sparkline->SetLineSize(3); // for renderresampled, linesize is on virtual image - $sparkline->RenderResampled(100, 20, 'lineColor'); - - $this->sparkline = $sparkline; - } - - function render() - { - $this->sparkline->Output(); - } -}
\ No newline at end of file diff --git a/modules/iView.php b/modules/iView.php deleted file mode 100644 index c35edafa50..0000000000 --- a/modules/iView.php +++ /dev/null @@ -1,27 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id: APIable.php 162 2008-01-14 04:27:21Z matt $ - * - * @package Piwik_Visualization - */ - -/** - * Piwik_ViewDataTable must create a $view attribute which implements this interface. - * - * @package Piwik_Visualization - */ -interface Piwik_iView -{ - /** - * Outputs the data. - * Either outputs html, xml, an image, nothing, etc. - * - * @return mixed - * - */ - function render(); -}
\ No newline at end of file diff --git a/modules/testMinimumPhpVersion.php b/modules/testMinimumPhpVersion.php deleted file mode 100644 index 52c7c6d608..0000000000 --- a/modules/testMinimumPhpVersion.php +++ /dev/null @@ -1,98 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later - * @version $Id: Common.php 168 2008-01-14 05:26:43Z matt $ - * - * @package Piwik - */ - -/** - * This file is executed before anything else. It checks the minimum Php version required to run Piwik. - * This is done here because on PHP4 piwik would output an error directly. - * Let's try to be user friendly :) - * - * @package Piwik - */ - -// we prefix the global variables -$piwik_minimumPhpVersion = '5.1.3'; -$piwik_currentVersion = phpversion(); - -if( version_compare($piwik_minimumPhpVersion , $piwik_currentVersion ) >= 0 ) -{ - $piwik_errorMessage = "<p><b>To run Piwik you need at least PHP version $piwik_minimumPhpVersion </b></p> - <p>Unfortunately it seems your webserver is using PHP version $piwik_currentVersion. </p> - <p>Please try to update your PHP version, Piwik is really worth it! Nowadays most web hosts - support PHP $piwik_minimumPhpVersion. </p>"; -} - -$piwik_zend_compatibility_mode = ini_get("zend.ze1_compatibility_mode"); - -if($piwik_zend_compatibility_mode == 1) -{ - $piwik_errorMessage = "<p><b>Piwik is not compatible with the directive <code>zend.ze1_compatibility_mode = On</code></b></p> - <p>It seems your php.ini file has <pre>zend.ze1_compatibility_mode = On</pre>It makes PHP5 behave like PHP4. - If you want to use Piwik you need to set <pre>zend.ze1_compatibility_mode = Off</pre> in your php.ini configuration file. You may have to ask your system administrator.</p>"; -} - -function Piwik_ExitWithMessage($message) -{ - $html = '<html> - <head> - <title>Piwik › Error</title> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> - <style> - html { background: #eee; } - body { - background: #fff; - color: #000; - font-family: Georgia, "Times New Roman", Times, serif; - margin-left: 20%; - margin-top: 25px; - margin-right: 20%; - padding: .2em 2em; - } - #h1 { - color: #006; - font-size: 45px; - font-weight: lighter; - } - #subh1 { - color: #879DBD; - font-size: 25px; - font-weight: lighter; - } - p, li, dt { - line-height: 140%; - padding-bottom: 2px; - } - a { color: #006; } - ul, ol { padding: 5px 5px 5px 20px; } - #logo { margin-bottom: 2em; } - code { margin-left: 40px; } - </style> - </head> - <body> - <span id="h1">Piwik </span><span id="subh1"> # open source web analytics</span> - <p>'.$message.'</p> - <ul> - <li><a target="_blank" href="misc/redirectToUrl.php?url=http://piwik.org">Piwik homepage</a></li> - <li><a target="_blank" href="misc/redirectToUrl.php?url=http://piwik.org/demo">Piwik demo</a></li> - </ul> - </body> - </html>'; - echo $html; - exit; -} - -if(isset($piwik_errorMessage)) -{ - Piwik_ExitWithMessage($piwik_errorMessage); -} - -// we now include the upgradephp package to define some functions used in piwik -// that may not be defined in the current php version -require_once "libs/upgradephp/upgrade.php";
\ No newline at end of file |