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

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/AssetManager.php2
-rw-r--r--core/CacheFile.php8
-rw-r--r--core/Common.php95
-rw-r--r--core/Filesystem.php266
-rw-r--r--core/Http.php7
-rw-r--r--core/Log.php8
-rw-r--r--core/Piwik.php291
-rw-r--r--core/PluginsManager.php12
-rw-r--r--core/ReportRenderer/Pdf.php7
-rw-r--r--core/Session.php4
-rw-r--r--core/Translate.php4
-rw-r--r--core/Translate/Writer.php6
-rw-r--r--core/Updates/0.2.10.php4
-rw-r--r--core/Updates/0.6.2.php3
-rw-r--r--js/index.php1
-rw-r--r--plugins/API/API.php26
-rw-r--r--plugins/CorePluginsAdmin/Controller.php7
-rw-r--r--plugins/CorePluginsAdmin/PluginInstaller.php6
-rw-r--r--plugins/CoreUpdater/Controller.php32
-rw-r--r--plugins/ImageGraph/API.php7
-rw-r--r--plugins/Installation/Controller.php20
-rw-r--r--plugins/Installation/FormDatabaseSetup.php12
-rw-r--r--plugins/Installation/ServerFilesGenerator.php134
-rw-r--r--plugins/LanguagesManager/API.php5
-rw-r--r--tests/PHPUnit/Core/CommonTest.php5
-rw-r--r--tests/PHPUnit/Core/PiwikTest.php5
-rw-r--r--tests/PHPUnit/Core/ReleaseCheckListTest.php6
27 files changed, 504 insertions, 479 deletions
diff --git a/core/AssetManager.php b/core/AssetManager.php
index af8e8a4bd4..1f4a190475 100644
--- a/core/AssetManager.php
+++ b/core/AssetManager.php
@@ -540,7 +540,7 @@ class AssetManager
$mergedFileDirectory = PIWIK_USER_PATH . '/' . self::MERGED_FILE_DIR;
if (!is_dir($mergedFileDirectory)) {
- Common::mkdir($mergedFileDirectory);
+ Filesystem::mkdir($mergedFileDirectory);
}
if (!is_writable($mergedFileDirectory)) {
diff --git a/core/CacheFile.php b/core/CacheFile.php
index addb926d6c..4666ee69a1 100644
--- a/core/CacheFile.php
+++ b/core/CacheFile.php
@@ -11,8 +11,6 @@
namespace Piwik;
use Exception;
-use Piwik\Piwik;
-use Piwik\Common;
/**
* Code originally inspired from OpenX
@@ -94,7 +92,7 @@ class CacheFile
protected function cleanupId($id)
{
- if (!Common::isValidFilename($id)) {
+ if (!Filesystem::isValidFilename($id)) {
throw new Exception("Invalid cache ID request $id");
}
return $id;
@@ -113,7 +111,7 @@ class CacheFile
return false;
}
if (!is_dir($this->cachePath)) {
- Common::mkdir($this->cachePath);
+ Filesystem::mkdir($this->cachePath);
}
if (!is_writable($this->cachePath)) {
return false;
@@ -176,6 +174,6 @@ class CacheFile
*/
public function deleteAll()
{
- Piwik::unlinkRecursive($this->cachePath, $deleteRootToo = false);
+ Filesystem::unlinkRecursive($this->cachePath, $deleteRootToo = false);
}
}
diff --git a/core/Common.php b/core/Common.php
index c9116c8cc1..311e3fdb84 100644
--- a/core/Common.php
+++ b/core/Common.php
@@ -11,11 +11,9 @@
namespace Piwik;
use Exception;
-use Piwik\IP;
+use Piwik\Plugins\UserCountry\LocationProvider\DefaultProvider;
use Piwik\Tracker;
use Piwik\Tracker\Cache;
-use Piwik\PluginsManager;
-use Piwik\Plugins\UserCountry\LocationProvider\DefaultProvider;
/**
* Static class providing functions used by both the CORE of Piwik and the visitor Tracking engine.
@@ -269,97 +267,6 @@ class Common
}
/*
- * File operations
- */
-
- /**
- * ending WITHOUT slash
- *
- * @return string
- */
- public static function getPathToPiwikRoot()
- {
- return realpath(dirname(__FILE__) . "/..");
- }
-
- /**
- * Create directory if permitted
- *
- * @param string $path
- * @param bool $denyAccess
- */
- public static function mkdir($path, $denyAccess = true)
- {
- if (!is_dir($path)) {
- // the mode in mkdir is modified by the current umask
- @mkdir($path, $mode = 0755, $recursive = true);
- }
-
- // try to overcome restrictive umask (mis-)configuration
- if (!is_writable($path)) {
- @chmod($path, 0755);
- if (!is_writable($path)) {
- @chmod($path, 0775);
-
- // enough! we're not going to make the directory world-writeable
- }
- }
-
- if ($denyAccess) {
- self::createHtAccess($path, $overwrite = false);
- }
- }
-
- /**
- * Create .htaccess file in specified directory
- *
- * Apache-specific; for IIS @see web.config
- *
- * @param string $path without trailing slash
- * @param bool $overwrite whether to overwrite an existing file or not
- * @param string $content
- */
- public static function createHtAccess($path, $overwrite = true, $content = "<Files \"*\">\n<IfModule mod_access.c>\nDeny from all\n</IfModule>\n<IfModule !mod_access_compat>\n<IfModule mod_authz_host.c>\nDeny from all\n</IfModule>\n</IfModule>\n<IfModule mod_access_compat>\nDeny from all\n</IfModule>\n</Files>\n")
- {
- if (self::isApache()) {
- $file = $path . '/.htaccess';
- if ($overwrite || !file_exists($file)) {
- @file_put_contents($file, $content);
- }
- }
- }
-
- /**
- * Get canonicalized absolute path
- * See http://php.net/realpath
- *
- * @param string $path
- * @return string canonicalized absolute path
- */
- public static function realpath($path)
- {
- if (file_exists($path)) {
- return realpath($path);
- }
- return $path;
- }
-
- /**
- * 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
- *
- */
- public static function isValidFilename($filename)
- {
- return (0 !== preg_match('/(^[a-zA-Z0-9]+([a-zA-Z_0-9.-]*))$/D', $filename));
- }
-
- /*
* String operations
*/
diff --git a/core/Filesystem.php b/core/Filesystem.php
new file mode 100644
index 0000000000..ab5be2bca0
--- /dev/null
+++ b/core/Filesystem.php
@@ -0,0 +1,266 @@
+<?php
+/**
+ * Piwik - Open source web analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ * @category Piwik
+ * @package Piwik
+ */
+namespace Piwik;
+
+use Exception;
+
+class Filesystem
+{
+ /**
+ * ending WITHOUT slash
+ *
+ * @return string
+ */
+ public static function getPathToPiwikRoot()
+ {
+ return realpath(dirname(__FILE__) . "/..");
+ }
+
+ /**
+ * Create .htaccess file in specified directory
+ *
+ * Apache-specific; for IIS @see web.config
+ *
+ * @param string $path without trailing slash
+ * @param bool $overwrite whether to overwrite an existing file or not
+ * @param string $content
+ */
+ public static function createHtAccess($path, $overwrite = true, $content = "<Files \"*\">\n<IfModule mod_access.c>\nDeny from all\n</IfModule>\n<IfModule !mod_access_compat>\n<IfModule mod_authz_host.c>\nDeny from all\n</IfModule>\n</IfModule>\n<IfModule mod_access_compat>\nDeny from all\n</IfModule>\n</Files>\n")
+ {
+ if (Common::isApache()) {
+ $file = $path . '/.htaccess';
+ if ($overwrite || !file_exists($file)) {
+ @file_put_contents($file, $content);
+ }
+ }
+ }
+
+ /**
+ * 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
+ *
+ */
+ public static function isValidFilename($filename)
+ {
+ return (0 !== preg_match('/(^[a-zA-Z0-9]+([a-zA-Z_0-9.-]*))$/D', $filename));
+ }
+
+ /**
+ * Get canonicalized absolute path
+ * See http://php.net/realpath
+ *
+ * @param string $path
+ * @return string canonicalized absolute path
+ */
+ public static function realpath($path)
+ {
+ if (file_exists($path)) {
+ return realpath($path);
+ }
+ return $path;
+ }
+
+ /**
+ * Create directory if permitted
+ *
+ * @param string $path
+ * @param bool $denyAccess
+ */
+ public static function mkdir($path, $denyAccess = true)
+ {
+ if (!is_dir($path)) {
+ // the mode in mkdir is modified by the current umask
+ @mkdir($path, $mode = 0755, $recursive = true);
+ }
+
+ // try to overcome restrictive umask (mis-)configuration
+ if (!is_writable($path)) {
+ @chmod($path, 0755);
+ if (!is_writable($path)) {
+ @chmod($path, 0775);
+ // enough! we're not going to make the directory world-writeable
+ }
+ }
+
+ if ($denyAccess) {
+ self::createHtAccess($path, $overwrite = false);
+ }
+ }
+
+ /**
+ * Checks if the filesystem Piwik stores sessions in is NFS or not. This
+ * check is done in order to avoid using file based sessions on NFS system,
+ * since on such a filesystem file locking can make file based sessions
+ * incredibly slow.
+ *
+ * Note: In order to figure this out, we try to run the 'df' program. If
+ * the 'exec' or 'shell_exec' functions are not available, we can't do
+ * the check.
+ *
+ * @return bool True if on an NFS filesystem, false if otherwise or if we
+ * can't use shell_exec or exec.
+ */
+ public static function checkIfFileSystemIsNFS()
+ {
+ $sessionsPath = Session::getSessionsDirectory();
+
+ // this command will display details for the filesystem that holds the $sessionsPath
+ // path, but only if its type is NFS. if not NFS, df will return one or less lines
+ // and the return code 1. if NFS, it will return 0 and at least 2 lines of text.
+ $command = "df -T -t nfs \"$sessionsPath\" 2>&1";
+
+ if (function_exists('exec')) // use exec
+ {
+ $output = $returnCode = null;
+ @exec($command, $output, $returnCode);
+
+ // check if filesystem is NFS
+ if ($returnCode == 0
+ && count($output) > 1
+ ) {
+ return true;
+ }
+ } else if (function_exists('shell_exec')) // use shell_exec
+ {
+ $output = @shell_exec($command);
+ if ($output) {
+ $output = explode("\n", $output);
+ if (count($output) > 1) // check if filesystem is NFS
+ {
+ return true;
+ }
+ }
+ }
+
+ return false; // not NFS, or we can't run a program to find out
+ }
+
+ /**
+ * Recursively find pathnames that match a pattern
+ * @see glob()
+ *
+ * @param string $sDir directory
+ * @param string $sPattern pattern
+ * @param int $nFlags glob() flags
+ * @return array
+ */
+ public static function globr($sDir, $sPattern, $nFlags = null)
+ {
+ if (($aFiles = \_glob("$sDir/$sPattern", $nFlags)) == false) {
+ $aFiles = array();
+ }
+ if (($aDirs = \_glob("$sDir/*", GLOB_ONLYDIR)) != false) {
+ foreach ($aDirs as $sSubDir) {
+ if (is_link($sSubDir)) {
+ continue;
+ }
+
+ $aSubFiles = self::globr($sSubDir, $sPattern, $nFlags);
+ $aFiles = array_merge($aFiles, $aSubFiles);
+ }
+ }
+ return $aFiles;
+ }
+
+ /**
+ * Recursively delete a directory
+ *
+ * @param string $dir Directory name
+ * @param boolean $deleteRootToo Delete specified top-level directory as well
+ */
+ public static function unlinkRecursive($dir, $deleteRootToo)
+ {
+ if (!$dh = @opendir($dir)) {
+ return;
+ }
+ while (false !== ($obj = readdir($dh))) {
+ if ($obj == '.' || $obj == '..') {
+ continue;
+ }
+
+ if (!@unlink($dir . '/' . $obj)) {
+ self::unlinkRecursive($dir . '/' . $obj, true);
+ }
+ }
+ closedir($dh);
+ if ($deleteRootToo) {
+ @rmdir($dir);
+ }
+ return;
+ }
+
+ /**
+ * Copy individual file from $source to $target.
+ *
+ * @param string $source eg. './tmp/latest/index.php'
+ * @param string $dest eg. './index.php'
+ * @param bool $excludePhp
+ * @throws Exception
+ * @return bool
+ */
+ public static function copy($source, $dest, $excludePhp = false)
+ {
+ static $phpExtensions = array('php', 'tpl', 'twig');
+
+ if ($excludePhp) {
+ $path_parts = pathinfo($source);
+ if (in_array($path_parts['extension'], $phpExtensions)) {
+ return true;
+ }
+ }
+
+ if (!@copy($source, $dest)) {
+ @chmod($dest, 0755);
+ if (!@copy($source, $dest)) {
+ $message = "Error while creating/copying file to <code>$dest</code>. <br />"
+ . Piwik::getErrorMessageMissingPermissions(self::getPathToPiwikRoot());
+ throw new Exception($message);
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Copy recursively from $source to $target.
+ *
+ * @param string $source eg. './tmp/latest'
+ * @param string $target eg. '.'
+ * @param bool $excludePhp
+ */
+ public static function copyRecursive($source, $target, $excludePhp = false)
+ {
+ if (is_dir($source)) {
+ self::mkdir($target, false);
+ $d = dir($source);
+ while (false !== ($entry = $d->read())) {
+ if ($entry == '.' || $entry == '..') {
+ continue;
+ }
+
+ $sourcePath = $source . '/' . $entry;
+ if (is_dir($sourcePath)) {
+ self::copyRecursive($sourcePath, $target . '/' . $entry, $excludePhp);
+ continue;
+ }
+ $destPath = $target . '/' . $entry;
+ self::copy($sourcePath, $destPath, $excludePhp);
+ }
+ $d->close();
+ } else {
+ self::copy($source, $target, $excludePhp);
+ }
+ }
+}
diff --git a/core/Http.php b/core/Http.php
index 9f3d52045d..0da5b04503 100644
--- a/core/Http.php
+++ b/core/Http.php
@@ -11,11 +11,6 @@
namespace Piwik;
use Exception;
-use Piwik\Config;
-use Piwik\Piwik;
-use Piwik\Common;
-use Piwik\IP;
-use Piwik\Version;
/**
* Server-side http client to retrieve content from remote servers, and optionally save to a local file.
@@ -80,7 +75,7 @@ class Http
$file = null;
if ($destinationPath) {
// Ensure destination directory exists
- Common::mkdir(dirname($destinationPath));
+ Filesystem::mkdir(dirname($destinationPath));
if (($file = @fopen($destinationPath, 'wb')) === false || !is_resource($file)) {
throw new Exception('Error while creating the file: ' . $destinationPath);
}
diff --git a/core/Log.php b/core/Log.php
index 48a9f6c429..a2720098dd 100644
--- a/core/Log.php
+++ b/core/Log.php
@@ -9,12 +9,10 @@
* @package Piwik
*/
namespace Piwik;
-use Piwik\Config;
-use Piwik\Common;
-use Piwik\Log\Exception;
-use Piwik\Log\Error;
use Piwik\Log\APICall;
+use Piwik\Log\Error;
+use Piwik\Log\Exception;
use Piwik\Log\Message;
/**
@@ -64,7 +62,7 @@ abstract class Log extends \Zend_Log
function addWriteToFile()
{
- Common::mkdir(dirname($this->logToFileFilename));
+ Filesystem::mkdir(dirname($this->logToFileFilename));
$writerFile = new \Zend_Log_Writer_Stream($this->logToFileFilename);
$writerFile->setFormatter($this->fileFormatter);
$this->addWriter($writerFile);
diff --git a/core/Piwik.php b/core/Piwik.php
index 469b1f80e6..d2f760ed7f 100644
--- a/core/Piwik.php
+++ b/core/Piwik.php
@@ -183,68 +183,6 @@ class Piwik
*/
/**
- * Copy recursively from $source to $target.
- *
- * @param string $source eg. './tmp/latest'
- * @param string $target eg. '.'
- * @param bool $excludePhp
- */
- static public function copyRecursive($source, $target, $excludePhp = false)
- {
- if (is_dir($source)) {
- Common::mkdir($target, false);
- $d = dir($source);
- while (false !== ($entry = $d->read())) {
- if ($entry == '.' || $entry == '..') {
- continue;
- }
-
- $sourcePath = $source . '/' . $entry;
- if (is_dir($sourcePath)) {
- self::copyRecursive($sourcePath, $target . '/' . $entry, $excludePhp);
- continue;
- }
- $destPath = $target . '/' . $entry;
- self::copy($sourcePath, $destPath, $excludePhp);
- }
- $d->close();
- } else {
- self::copy($source, $target, $excludePhp);
- }
- }
-
- /**
- * Copy individual file from $source to $target.
- *
- * @param string $source eg. './tmp/latest/index.php'
- * @param string $dest eg. './index.php'
- * @param bool $excludePhp
- * @throws Exception
- * @return bool
- */
- static public function copy($source, $dest, $excludePhp = false)
- {
- static $phpExtensions = array('php', 'tpl', 'twig');
-
- if ($excludePhp) {
- $path_parts = pathinfo($source);
- if (in_array($path_parts['extension'], $phpExtensions)) {
- return true;
- }
- }
-
- if (!@copy($source, $dest)) {
- @chmod($dest, 0755);
- if (!@copy($source, $dest)) {
- $message = "Error while creating/copying file to <code>$dest</code>. <br />"
- . self::getErrorMessageMissingPermissions(Common::getPathToPiwikRoot());
- throw new Exception($message);
- }
- }
- return true;
- }
-
- /**
* Returns friendly error message explaining how to fix permissions
*
* @param string $path to the directory missing permissions
@@ -269,60 +207,6 @@ class Piwik
}
/**
- * Recursively delete a directory
- *
- * @param string $dir Directory name
- * @param boolean $deleteRootToo Delete specified top-level directory as well
- */
- static public function unlinkRecursive($dir, $deleteRootToo)
- {
- if (!$dh = @opendir($dir)) {
- return;
- }
- while (false !== ($obj = readdir($dh))) {
- if ($obj == '.' || $obj == '..') {
- continue;
- }
-
- if (!@unlink($dir . '/' . $obj)) {
- self::unlinkRecursive($dir . '/' . $obj, true);
- }
- }
- closedir($dh);
- if ($deleteRootToo) {
- @rmdir($dir);
- }
- return;
- }
-
- /**
- * Recursively find pathnames that match a pattern
- * @see glob()
- *
- * @param string $sDir directory
- * @param string $sPattern pattern
- * @param int $nFlags glob() flags
- * @return array
- */
- public static function globr($sDir, $sPattern, $nFlags = null)
- {
- if (($aFiles = \_glob("$sDir/$sPattern", $nFlags)) == false) {
- $aFiles = array();
- }
- if (($aDirs = \_glob("$sDir/*", GLOB_ONLYDIR)) != false) {
- foreach ($aDirs as $sSubDir) {
- if (is_link($sSubDir)) {
- continue;
- }
-
- $aSubFiles = self::globr($sSubDir, $sPattern, $nFlags);
- $aFiles = array_merge($aFiles, $aSubFiles);
- }
- }
- return $aFiles;
- }
-
- /**
* Returns the help text displayed to suggest which command to run to give writable access to a file or directory
*
* @param string $realpath
@@ -351,7 +235,7 @@ class Piwik
$directoryList = '';
foreach ($resultCheck as $dir => $bool) {
- $realpath = Common::realpath($dir);
+ $realpath = Filesystem::realpath($dir);
if (!empty($realpath) && $bool === false) {
$directoryList .= self::getMakeWritableCommand($realpath);
}
@@ -359,7 +243,7 @@ class Piwik
// Also give the chown since the chmod is only 755
if (!Common::isWindows()) {
- $realpath = Common::realpath(PIWIK_INCLUDE_PATH . '/');
+ $realpath = Filesystem::realpath(PIWIK_INCLUDE_PATH . '/');
$directoryList = "<code>chown -R www-data:www-data " . $realpath . "</code><br/>" . $directoryList;
}
@@ -391,10 +275,10 @@ class Piwik
// Create an empty directory
$isFile = strpos($directoryToCheck, '.') !== false;
if (!$isFile && !file_exists($directoryToCheck)) {
- Common::mkdir($directoryToCheck);
+ Filesystem::mkdir($directoryToCheck);
}
- $directory = Common::realpath($directoryToCheck);
+ $directory = Filesystem::realpath($directoryToCheck);
$resultCheck[$directory] = false;
if ($directory !== false // realpath() returns FALSE on failure
&& is_writable($directoryToCheck)
@@ -430,7 +314,7 @@ class Piwik
*/
static public function getAutoUpdateMakeWritableMessage()
{
- $realpath = Common::realpath(PIWIK_INCLUDE_PATH . '/');
+ $realpath = Filesystem::realpath(PIWIK_INCLUDE_PATH . '/');
$message = '';
$message .= "<code>chown -R www-data:www-data " . $realpath . "</code><br />";
$message .= "<code>chmod -R 0755 " . $realpath . "</code><br />";
@@ -439,123 +323,6 @@ class Piwik
}
/**
- * Generate default robots.txt, favicon.ico, etc to suppress
- * 404 (Not Found) errors in the web server logs, if Piwik
- * is installed in the web root (or top level of subdomain).
- *
- * @see misc/crossdomain.xml
- */
- static public function createWebRootFiles()
- {
- $filesToCreate = array(
- '/robots.txt',
- '/favicon.ico',
- );
- foreach ($filesToCreate as $file) {
- @file_put_contents(PIWIK_DOCUMENT_ROOT . $file, '');
- }
- }
-
- /**
- * Generate Apache .htaccess files to restrict access
- */
- static public function createHtAccessFiles()
- {
- // deny access to these folders
- $directoriesToProtect = array(
- '/config',
- '/core',
- '/lang',
- '/tmp',
- );
- foreach ($directoriesToProtect as $directoryToProtect) {
- Common::createHtAccess(PIWIK_INCLUDE_PATH . $directoryToProtect, $overwrite = true);
- }
-
- // Allow/Deny lives in different modules depending on the Apache version
- $allow = "<IfModule mod_access.c>\nAllow from all\n</IfModule>\n<IfModule !mod_access_compat>\n<IfModule mod_authz_host.c>\nAllow from all\n</IfModule>\n</IfModule>\n<IfModule mod_access_compat>\nAllow from all\n</IfModule>\n";
- $deny = "<IfModule mod_access.c>\nDeny from all\n</IfModule>\n<IfModule !mod_access_compat>\n<IfModule mod_authz_host.c>\nDeny from all\n</IfModule>\n</IfModule>\n<IfModule mod_access_compat>\nDeny from all\n</IfModule>\n";
-
- // more selective allow/deny filters
- $allowAny = "<Files \"*\">\n" . $allow . "Satisfy any\n</Files>\n";
- $allowStaticAssets = "<Files ~ \"\\.(test\.php|gif|ico|jpg|png|svg|js|css|swf)$\">\n" . $allow . "Satisfy any\n</Files>\n";
- $denyDirectPhp = "<Files ~ \"\\.(php|php4|php5|inc|tpl|in|twig)$\">\n" . $deny . "</Files>\n";
-
- $directoriesToProtect = array(
- '/js' => $allowAny,
- '/libs' => $denyDirectPhp . $allowStaticAssets,
- '/vendor' => $denyDirectPhp . $allowStaticAssets,
- '/plugins' => $denyDirectPhp . $allowStaticAssets,
- '/misc/user' => $denyDirectPhp . $allowStaticAssets,
- );
- foreach ($directoriesToProtect as $directoryToProtect => $content) {
- Common::createHtAccess(PIWIK_INCLUDE_PATH . $directoryToProtect, $overwrite = true, $content);
- }
- }
-
- /**
- * Generate IIS web.config files to restrict access
- *
- * Note: for IIS 7 and above
- */
- static public function createWebConfigFiles()
- {
- @file_put_contents(PIWIK_INCLUDE_PATH . '/web.config',
- '<?xml version="1.0" encoding="UTF-8"?>
-<configuration>
- <system.webServer>
- <security>
- <requestFiltering>
- <hiddenSegments>
- <add segment="config" />
- <add segment="core" />
- <add segment="lang" />
- <add segment="tmp" />
- </hiddenSegments>
- <fileExtensions>
- <add fileExtension=".tpl" allowed="false" />
- <add fileExtension=".twig" allowed="false" />
- <add fileExtension=".php4" allowed="false" />
- <add fileExtension=".php5" allowed="false" />
- <add fileExtension=".inc" allowed="false" />
- <add fileExtension=".in" allowed="false" />
- </fileExtensions>
- </requestFiltering>
- </security>
- <directoryBrowse enabled="false" />
- <defaultDocument>
- <files>
- <remove value="index.php" />
- <add value="index.php" />
- </files>
- </defaultDocument>
- </system.webServer>
-</configuration>');
-
- // deny direct access to .php files
- $directoriesToProtect = array(
- '/libs',
- '/vendor',
- '/plugins',
- );
- foreach ($directoriesToProtect as $directoryToProtect) {
- @file_put_contents(PIWIK_INCLUDE_PATH . $directoryToProtect . '/web.config',
- '<?xml version="1.0" encoding="UTF-8"?>
-<configuration>
- <system.webServer>
- <security>
- <requestFiltering>
- <denyUrlSequences>
- <add sequence=".php" />
- </denyUrlSequences>
- </requestFiltering>
- </security>
- </system.webServer>
-</configuration>');
- }
- }
-
- /**
* Get file integrity information (in PIWIK_INCLUDE_PATH).
*
* @return array(bool, string, ...) Return code (true/false), followed by zero or more error messages
@@ -2012,54 +1779,6 @@ class Piwik
}
/**
- * Checks if the filesystem Piwik stores sessions in is NFS or not. This
- * check is done in order to avoid using file based sessions on NFS system,
- * since on such a filesystem file locking can make file based sessions
- * incredibly slow.
- *
- * Note: In order to figure this out, we try to run the 'df' program. If
- * the 'exec' or 'shell_exec' functions are not available, we can't do
- * the check.
- *
- * @return bool True if on an NFS filesystem, false if otherwise or if we
- * can't use shell_exec or exec.
- */
- public static function checkIfFileSystemIsNFS()
- {
- $sessionsPath = Session::getSessionsDirectory();
-
- // this command will display details for the filesystem that holds the $sessionsPath
- // path, but only if its type is NFS. if not NFS, df will return one or less lines
- // and the return code 1. if NFS, it will return 0 and at least 2 lines of text.
- $command = "df -T -t nfs \"$sessionsPath\" 2>&1";
-
- if (function_exists('exec')) // use exec
- {
- $output = $returnCode = null;
- @exec($command, $output, $returnCode);
-
- // check if filesystem is NFS
- if ($returnCode == 0
- && count($output) > 1
- ) {
- return true;
- }
- } else if (function_exists('shell_exec')) // use shell_exec
- {
- $output = @shell_exec($command);
- if ($output) {
- $output = explode("\n", $output);
- if (count($output) > 1) // check if filesystem is NFS
- {
- return true;
- }
- }
- }
-
- return false; // not NFS, or we can't run a program to find out
- }
-
- /**
* Returns the option name of the option that stores the time the archive.php
* script was last run.
*
diff --git a/core/PluginsManager.php b/core/PluginsManager.php
index b12ab0cd45..2df4707994 100644
--- a/core/PluginsManager.php
+++ b/core/PluginsManager.php
@@ -11,12 +11,8 @@
namespace Piwik;
-use Piwik\Config;
-use Piwik\Piwik;
-use Piwik\Common;
-use Piwik\EventDispatcher;
-use Piwik\Translate;
use Piwik\Plugin\MetadataLoader;
+use Piwik\Translate;
require_once PIWIK_INCLUDE_PATH . '/core/EventDispatcher.php';
@@ -210,7 +206,7 @@ class PluginsManager
public static function deletePluginFromFilesystem($plugin)
{
- Piwik::unlinkRecursive(PIWIK_INCLUDE_PATH . '/plugins/' . $plugin, $deleteRootToo = true);
+ Filesystem::unlinkRecursive(PIWIK_INCLUDE_PATH . '/plugins/' . $plugin, $deleteRootToo = true);
}
/**
@@ -321,7 +317,7 @@ class PluginsManager
{
$existingPlugins = $this->readPluginsDirectory();
$isPluginInFilesystem = array_search($pluginName, $existingPlugins) !== false;
- return Common::isValidFilename($pluginName)
+ return Filesystem::isValidFilename($pluginName)
&& $isPluginInFilesystem;
}
@@ -497,7 +493,7 @@ class PluginsManager
$pluginFileName = sprintf("%s/%s.php", $pluginName, $pluginName);
$pluginClassName = $pluginName;
- if (!Common::isValidFilename($pluginName)) {
+ if (!Filesystem::isValidFilename($pluginName)) {
throw new \Exception(sprintf("The plugin filename '%s' is not a valid filename", $pluginFileName));
}
diff --git a/core/ReportRenderer/Pdf.php b/core/ReportRenderer/Pdf.php
index 842908de72..d548523eae 100644
--- a/core/ReportRenderer/Pdf.php
+++ b/core/ReportRenderer/Pdf.php
@@ -11,9 +11,10 @@
namespace Piwik\ReportRenderer;
use Piwik\Common;
-use Piwik\TCPDF;
-use Piwik\ReportRenderer;
+use Piwik\Filesystem;
use Piwik\Plugins\API\API;
+use Piwik\ReportRenderer;
+use Piwik\TCPDF;
/**
* @see libs/tcpdf
@@ -378,7 +379,7 @@ class Pdf extends ReportRenderer
if ($logoHeight < 16) {
$topMargin = 2;
}
- $path = Common::getPathToPiwikRoot() . "/" . $rowMetadata['logo'];
+ $path = Filesystem::getPathToPiwikRoot() . "/" . $rowMetadata['logo'];
if (file_exists($path)) {
$this->TCPDF->Image($path, $posX + ($leftMargin = 2), $posY + $topMargin, $logoWidth / 4);
}
diff --git a/core/Session.php b/core/Session.php
index 59e02a89a2..d89df96ea1 100644
--- a/core/Session.php
+++ b/core/Session.php
@@ -84,7 +84,7 @@ class Session extends Zend_Session
// for "files", use our own folder to prevent local session file hijacking
$sessionPath = self::getSessionsDirectory();
// We always call mkdir since it also chmods the directory which might help when permissions were reverted for some reasons
- Common::mkdir($sessionPath);
+ Filesystem::mkdir($sessionPath);
@ini_set('session.save_handler', 'files');
@ini_set('session.save_path', $sessionPath);
@@ -131,7 +131,7 @@ class Session extends Zend_Session
$message = sprintf("Error: %s %s %s\n<pre>Debug: the original error was \n%s</pre>",
Piwik_Translate('General_ExceptionUnableToStartSession'),
- Piwik::getErrorMessageMissingPermissions(Common::getPathToPiwikRoot() . '/tmp/sessions/'),
+ Piwik::getErrorMessageMissingPermissions(Filesystem::getPathToPiwikRoot() . '/tmp/sessions/'),
$enableDbSessions,
$e->getMessage()
);
diff --git a/core/Translate.php b/core/Translate.php
index dbb6c6d3f6..c36410f505 100644
--- a/core/Translate.php
+++ b/core/Translate.php
@@ -10,8 +10,6 @@
*/
namespace Piwik;
use Exception;
-use Piwik\Config;
-use Piwik\Common;
/**
* @package Piwik
@@ -104,7 +102,7 @@ class Translate
private function loadCoreTranslationFile($language)
{
$path = PIWIK_INCLUDE_PATH . '/lang/' . $language . '.json';
- if (!Common::isValidFilename($language) || !is_readable($path)) {
+ if (!Filesystem::isValidFilename($language) || !is_readable($path)) {
throw new Exception(Piwik_TranslateException('General_ExceptionLanguageFileNotFound', array($language)));
}
$data = file_get_contents($path);
diff --git a/core/Translate/Writer.php b/core/Translate/Writer.php
index 914914955e..4360b1ecbf 100644
--- a/core/Translate/Writer.php
+++ b/core/Translate/Writer.php
@@ -12,7 +12,7 @@
namespace Piwik\Translate;
use Exception;
-use Piwik\Common;
+use Piwik\Filesystem;
use Piwik\PluginsManager;
use Piwik\Translate\Filter\FilterAbstract;
use Piwik\Translate\Validate\ValidateAbstract;
@@ -249,7 +249,7 @@ class Writer
$path = $this->getTranslationPath();
- Common::mkdir(dirname($path));
+ Filesystem::mkdir(dirname($path));
return file_put_contents($path, $this->__toString());
}
@@ -270,7 +270,7 @@ class Writer
$path = $this->getTemporaryTranslationPath();
- Common::mkdir(dirname($path));
+ Filesystem::mkdir(dirname($path));
return file_put_contents($path, $this->__toString());
}
diff --git a/core/Updates/0.2.10.php b/core/Updates/0.2.10.php
index 588c3f98ff..a378dccd51 100644
--- a/core/Updates/0.2.10.php
+++ b/core/Updates/0.2.10.php
@@ -8,8 +8,8 @@
* @category Piwik
* @package Updates
*/
-use Piwik\Piwik;
use Piwik\Common;
+use Piwik\Filesystem;
use Piwik\Updater;
use Piwik\Updates;
@@ -66,7 +66,7 @@ class Piwik_Updates_0_2_10 extends Updates
);
foreach ($obsoleteDirectories as $dir) {
if (file_exists(PIWIK_INCLUDE_PATH . $dir)) {
- Piwik::unlinkRecursive(PIWIK_INCLUDE_PATH . $dir, true);
+ Filesystem::unlinkRecursive(PIWIK_INCLUDE_PATH . $dir, true);
}
}
}
diff --git a/core/Updates/0.6.2.php b/core/Updates/0.6.2.php
index af541713a2..0651f2f676 100644
--- a/core/Updates/0.6.2.php
+++ b/core/Updates/0.6.2.php
@@ -8,6 +8,7 @@
* @category Piwik
* @package Updates
*/
+use Piwik\Filesystem;
use Piwik\Piwik;
use Piwik\Plugins\SitesManager\API;
use Piwik\Tracker\Cache;
@@ -34,7 +35,7 @@ class Piwik_Updates_0_6_2 extends Updates
);
foreach ($obsoleteDirectories as $dir) {
if (file_exists($dir)) {
- Piwik::unlinkRecursive($dir, true);
+ Filesystem::unlinkRecursive($dir, true);
}
}
diff --git a/js/index.php b/js/index.php
index 721e3353ef..5d8ec0a41b 100644
--- a/js/index.php
+++ b/js/index.php
@@ -26,6 +26,7 @@ define('PIWIK_USER_PATH', '..');
require_once PIWIK_INCLUDE_PATH . '/libs/upgradephp/upgrade.php';
require_once PIWIK_INCLUDE_PATH . '/core/Piwik.php';
+require_once PIWIK_INCLUDE_PATH . '/core/ProxyHttp.php';
$file = '../piwik.js';
diff --git a/plugins/API/API.php b/plugins/API/API.php
index d26b46db47..19cade72f1 100644
--- a/plugins/API/API.php
+++ b/plugins/API/API.php
@@ -10,19 +10,19 @@
*/
namespace Piwik\Plugins\API;
-use Piwik\API\Request;
use Piwik\API\Proxy;
+use Piwik\API\Request;
+use Piwik\Config;
use Piwik\DataTable\Filter\ColumnDelete;
use Piwik\DataTable\Row;
+use Piwik\DataTable;
+use Piwik\Date;
+use Piwik\Filesystem;
use Piwik\Metrics;
use Piwik\Piwik;
-use Piwik\Common;
-use Piwik\Config;
-use Piwik\Date;
-use Piwik\DataTable;
use Piwik\Tracker\GoalManager;
-use Piwik\Version;
use Piwik\Translate;
+use Piwik\Version;
require_once PIWIK_INCLUDE_PATH . '/core/Config.php';
@@ -284,14 +284,14 @@ class API
{
$logo = 'plugins/Zeitgeist/images/logo.png';
if (Config::getInstance()->branding['use_custom_logo'] == 1
- && file_exists(Common::getPathToPiwikRoot() . '/misc/user/logo.png')
+ && file_exists(Filesystem::getPathToPiwikRoot() . '/misc/user/logo.png')
) {
$logo = 'misc/user/logo.png';
}
if (!$pathOnly) {
return Piwik::getPiwikUrl() . $logo;
}
- return Common::getPathToPiwikRoot() . '/' . $logo;
+ return Filesystem::getPathToPiwikRoot() . '/' . $logo;
}
/**
@@ -304,14 +304,14 @@ class API
{
$logo = 'plugins/Zeitgeist/images/logo-header.png';
if (Config::getInstance()->branding['use_custom_logo'] == 1
- && file_exists(Common::getPathToPiwikRoot() . '/misc/user/logo-header.png')
+ && file_exists(Filesystem::getPathToPiwikRoot() . '/misc/user/logo-header.png')
) {
$logo = 'misc/user/logo-header.png';
}
if (!$pathOnly) {
return Piwik::getPiwikUrl() . $logo;
}
- return Common::getPathToPiwikRoot() . '/' . $logo;
+ return Filesystem::getPathToPiwikRoot() . '/' . $logo;
}
/**
@@ -325,14 +325,14 @@ class API
{
$logo = 'plugins/Zeitgeist/images/logo.svg';
if (Config::getInstance()->branding['use_custom_logo'] == 1
- && file_exists(Common::getPathToPiwikRoot() . '/misc/user/logo.svg')
+ && file_exists(Filesystem::getPathToPiwikRoot() . '/misc/user/logo.svg')
) {
$logo = 'misc/user/logo.svg';
}
if (!$pathOnly) {
return Piwik::getPiwikUrl() . $logo;
}
- return Common::getPathToPiwikRoot() . '/' . $logo;
+ return Filesystem::getPathToPiwikRoot() . '/' . $logo;
}
/**
@@ -346,7 +346,7 @@ class API
/* We always have our application logo */
return true;
} else if (Config::getInstance()->branding['use_custom_logo'] == 1
- && file_exists(Common::getPathToPiwikRoot() . '/misc/user/logo.svg')
+ && file_exists(Filesystem::getPathToPiwikRoot() . '/misc/user/logo.svg')
) {
return true;
}
diff --git a/plugins/CorePluginsAdmin/Controller.php b/plugins/CorePluginsAdmin/Controller.php
index d5ae70cf41..867a645953 100644
--- a/plugins/CorePluginsAdmin/Controller.php
+++ b/plugins/CorePluginsAdmin/Controller.php
@@ -10,12 +10,13 @@
*/
namespace Piwik\Plugins\CorePluginsAdmin;
-use Piwik\Piwik;
use Piwik\Common;
use Piwik\Config;
+use Piwik\Filesystem;
+use Piwik\Piwik;
use Piwik\Plugin;
-use Piwik\View;
use Piwik\Url;
+use Piwik\View;
/**
*
@@ -195,7 +196,7 @@ class Controller extends \Piwik\Controller\Admin
$pluginName = $this->initPluginModification();
$uninstalled = \Piwik\PluginsManager::getInstance()->uninstallPlugin($pluginName);
if (!$uninstalled) {
- $path = Common::getPathToPiwikRoot() . '/plugins/' . $pluginName . '/';
+ $path = Filesystem::getPathToPiwikRoot() . '/plugins/' . $pluginName . '/';
$messagePermissions = Piwik::getErrorMessageMissingPermissions($path);
$messageIntro = Piwik_Translate("Warning: \"%s\" could not be uninstalled. Piwik did not have enough permission to delete the files in $path. ",
diff --git a/plugins/CorePluginsAdmin/PluginInstaller.php b/plugins/CorePluginsAdmin/PluginInstaller.php
index 0fa791c795..eb7cf7095c 100644
--- a/plugins/CorePluginsAdmin/PluginInstaller.php
+++ b/plugins/CorePluginsAdmin/PluginInstaller.php
@@ -9,7 +9,7 @@
* @package CorePluginsAdmin
*/
namespace Piwik\Plugins\CorePluginsAdmin;
-use Piwik\Http;
+use Piwik\Filesystem;
use Piwik\Piwik;
use Piwik\Unzip;
@@ -93,7 +93,7 @@ class PluginInstaller
$pluginTargetPath = PIWIK_USER_PATH . self::PATH_TO_EXTRACT . $this->pluginName;
$this->removeFolderIfExists($pluginTargetPath);
- Piwik::copyRecursive($tmpPluginFolder, $pluginTargetPath);
+ Filesystem::copyRecursive($tmpPluginFolder, $pluginTargetPath);
}
/**
@@ -102,7 +102,7 @@ class PluginInstaller
private function removeFolderIfExists($pathExtracted)
{
if (file_exists($pathExtracted)) {
- Piwik::unlinkRecursive($pathExtracted, true);
+ Filesystem::unlinkRecursive($pathExtracted, true);
}
}
diff --git a/plugins/CoreUpdater/Controller.php b/plugins/CoreUpdater/Controller.php
index 6853dc3cc9..ae48b8e8ce 100644
--- a/plugins/CoreUpdater/Controller.php
+++ b/plugins/CoreUpdater/Controller.php
@@ -13,19 +13,19 @@ namespace Piwik\Plugins\CoreUpdater;
use Exception;
use Piwik\API\Request;
use Piwik\ArchiveProcessor\Rules;
-use Piwik\Config;
-use Piwik\Piwik;
use Piwik\Common;
+use Piwik\Config;
+use Piwik\Filesystem;
use Piwik\Http;
+use Piwik\Piwik;
+use Piwik\Plugins\LanguagesManager\LanguagesManager;
+use Piwik\Unzip;
+use Piwik\UpdateCheck;
use Piwik\Updater;
-use Piwik\View;
+use Piwik\Updater_UpdateErrorException;
use Piwik\Version;
-use Piwik\UpdateCheck;
-use Piwik\Unzip;
+use Piwik\View;
use Piwik\View\OneClickDone;
-use Piwik\Plugins\CoreUpdater\CoreUpdater;
-use Piwik\Plugins\LanguagesManager\LanguagesManager;
-use Piwik\Updater_UpdateErrorException;
/**
*
@@ -138,7 +138,7 @@ class Controller extends \Piwik\Controller
$this->pathRootExtractedPiwik = $pathExtracted . 'piwik';
if (file_exists($this->pathRootExtractedPiwik)) {
- Piwik::unlinkRecursive($this->pathRootExtractedPiwik, true);
+ Filesystem::unlinkRecursive($this->pathRootExtractedPiwik, true);
}
$archive = Unzip::factory('PclZip', $this->pathPiwikZip);
@@ -173,7 +173,7 @@ class Controller extends \Piwik\Controller
{
$configFileBefore = PIWIK_USER_PATH . '/config/global.ini.php';
$configFileAfter = PIWIK_USER_PATH . self::CONFIG_FILE_BACKUP;
- Piwik::copy($configFileBefore, $configFileAfter);
+ Filesystem::copy($configFileBefore, $configFileAfter);
}
private function oneClick_Copy()
@@ -189,7 +189,7 @@ class Controller extends \Piwik\Controller
* Copy all files to PIWIK_INCLUDE_PATH.
* These files are accessed through the dispatcher.
*/
- Piwik::copyRecursive($this->pathRootExtractedPiwik, PIWIK_INCLUDE_PATH);
+ Filesystem::copyRecursive($this->pathRootExtractedPiwik, PIWIK_INCLUDE_PATH);
/*
* These files are visible in the web root and are generally
@@ -206,23 +206,23 @@ class Controller extends \Piwik\Controller
);
foreach ($specialCases as $file) {
- Piwik::copy($this->pathRootExtractedPiwik . $file, PIWIK_DOCUMENT_ROOT . $file);
+ Filesystem::copy($this->pathRootExtractedPiwik . $file, PIWIK_DOCUMENT_ROOT . $file);
}
/*
* Copy the non-PHP files (e.g., images, css, javascript)
*/
- Piwik::copyRecursive($this->pathRootExtractedPiwik, PIWIK_DOCUMENT_ROOT, true);
+ Filesystem::copyRecursive($this->pathRootExtractedPiwik, PIWIK_DOCUMENT_ROOT, true);
}
/*
* Config files may be user (account) specific
*/
if (PIWIK_INCLUDE_PATH !== PIWIK_USER_PATH) {
- Piwik::copyRecursive($this->pathRootExtractedPiwik . '/config', PIWIK_USER_PATH . '/config');
+ Filesystem::copyRecursive($this->pathRootExtractedPiwik . '/config', PIWIK_USER_PATH . '/config');
}
- Piwik::unlinkRecursive($this->pathRootExtractedPiwik, true);
+ Filesystem::unlinkRecursive($this->pathRootExtractedPiwik, true);
if (function_exists('apc_clear_cache')) {
apc_clear_cache(); // clear the system (aka 'opcode') cache
@@ -289,7 +289,7 @@ class Controller extends \Piwik\Controller
private function doWelcomeUpdates($view, $componentsWithUpdateFile)
{
$view->new_piwik_version = Version::VERSION;
- $view->commandUpgradePiwik = "<br /><code>php " . Common::getPathToPiwikRoot() . "/index.php -- \"module=CoreUpdater\" </code>";
+ $view->commandUpgradePiwik = "<br /><code>php " . Filesystem::getPathToPiwikRoot() . "/index.php -- \"module=CoreUpdater\" </code>";
$pluginNamesToUpdate = array();
$coreToUpdate = false;
diff --git a/plugins/ImageGraph/API.php b/plugins/ImageGraph/API.php
index 6266bf9ed2..8cf9850ce1 100644
--- a/plugins/ImageGraph/API.php
+++ b/plugins/ImageGraph/API.php
@@ -11,12 +11,13 @@
namespace Piwik\Plugins\ImageGraph;
use Exception;
+use Piwik\Common;
+use Piwik\Filesystem;
use Piwik\Period;
use Piwik\Piwik;
-use Piwik\Common;
-use Piwik\Translate;
use Piwik\Plugins\API\API as MetaAPI;
use Piwik\Plugins\ImageGraph\StaticGraph;
+use Piwik\Translate;
/**
* The ImageGraph.get API call lets you generate beautiful static PNG Graphs for any existing Piwik report.
@@ -510,7 +511,7 @@ class API
$fileName = self::$DEFAULT_PARAMETERS[$graphType][self::FILENAME_KEY] . '_' . $apiModule . '_' . $apiAction . $idGoal . ' ' . str_replace(',', '-', $date) . ' ' . $idSite . '.png';
$fileName = str_replace(array(' ', '/'), '_', $fileName);
- if (!Common::isValidFilename($fileName)) {
+ if (!Filesystem::isValidFilename($fileName)) {
throw new Exception('Error: Image graph filename ' . $fileName . ' is not valid.');
}
diff --git a/plugins/Installation/Controller.php b/plugins/Installation/Controller.php
index 5df88f94f4..106023195d 100644
--- a/plugins/Installation/Controller.php
+++ b/plugins/Installation/Controller.php
@@ -18,6 +18,7 @@ use Piwik\Config;
use Piwik\DataAccess\ArchiveTableCreator;
use Piwik\Db\Adapter;
use Piwik\Db;
+use Piwik\Filesystem;
use Piwik\Http;
use Piwik\Piwik;
use Piwik\Plugins\LanguagesManager\LanguagesManager;
@@ -63,6 +64,16 @@ class Controller extends \Piwik\Controller\Admin
Piwik_PostEvent('InstallationController.construct', array($this));
}
+ protected static function initServerFilesForSecurity()
+ {
+ if (Common::isIIS()) {
+ ServerFilesGenerator::createWebConfigFiles();
+ } else {
+ ServerFilesGenerator::createHtAccessFiles();
+ }
+ ServerFilesGenerator::createWebRootFiles();
+ }
+
/**
* Get installation steps
*
@@ -720,12 +731,7 @@ class Controller extends \Piwik\Controller\Admin
$infos['can_auto_update'] = Piwik::canAutoUpdate();
- if (Common::isIIS()) {
- Piwik::createWebConfigFiles();
- } else {
- Piwik::createHtAccessFiles();
- }
- Piwik::createWebRootFiles();
+ self::initServerFilesForSecurity();
$infos['phpVersion_minimum'] = $piwik_minimumPHPVersion;
$infos['phpVersion'] = PHP_VERSION;
@@ -858,7 +864,7 @@ class Controller extends \Piwik\Controller\Admin
}
// check if filesystem is NFS, if it is file based sessions won't work properly
- $infos['is_nfs'] = Piwik::checkIfFileSystemIsNFS();
+ $infos['is_nfs'] = Filesystem::checkIfFileSystemIsNFS();
// determine whether there are any errors/warnings from the checks done above
$infos['has_errors'] = false;
diff --git a/plugins/Installation/FormDatabaseSetup.php b/plugins/Installation/FormDatabaseSetup.php
index 71f4643c8a..84efb6e698 100644
--- a/plugins/Installation/FormDatabaseSetup.php
+++ b/plugins/Installation/FormDatabaseSetup.php
@@ -10,14 +10,14 @@
*/
namespace Piwik\Plugins\Installation;
-use Piwik\Db\Adapter;
-use Piwik\Piwik;
-use Piwik\Common;
-use Piwik\QuickForm2;
use Exception;
-use HTML_QuickForm2_Rule;
use HTML_QuickForm2_DataSource_Array;
use HTML_QuickForm2_Factory;
+use HTML_QuickForm2_Rule;
+use Piwik\Db\Adapter;
+use Piwik\Filesystem;
+use Piwik\Piwik;
+use Piwik\QuickForm2;
use Zend_Db_Adapter_Exception;
/**
@@ -309,7 +309,7 @@ class FormDatabaseSetup_Rule_checkValidFilename extends HTML_QuickForm2_Rule
{
$prefix = $this->owner->getValue();
return empty($prefix)
- || Common::isValidFilename($prefix);
+ || Filesystem::isValidFilename($prefix);
}
}
diff --git a/plugins/Installation/ServerFilesGenerator.php b/plugins/Installation/ServerFilesGenerator.php
new file mode 100644
index 0000000000..2fbf591a21
--- /dev/null
+++ b/plugins/Installation/ServerFilesGenerator.php
@@ -0,0 +1,134 @@
+<?php
+/**
+ * Piwik - Open source web analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ * @category Piwik_Plugins
+ * @package Installation
+ */
+namespace Piwik\Plugins\Installation;
+
+use Piwik\Filesystem;
+
+class ServerFilesGenerator
+{
+
+ /**
+ * Generate Apache .htaccess files to restrict access
+ */
+ public static function createHtAccessFiles()
+ {
+ // deny access to these folders
+ $directoriesToProtect = array(
+ '/config',
+ '/core',
+ '/lang',
+ '/tmp',
+ );
+ foreach ($directoriesToProtect as $directoryToProtect) {
+ Filesystem::createHtAccess(PIWIK_INCLUDE_PATH . $directoryToProtect, $overwrite = true);
+ }
+
+ // Allow/Deny lives in different modules depending on the Apache version
+ $allow = "<IfModule mod_access.c>\nAllow from all\n</IfModule>\n<IfModule !mod_access_compat>\n<IfModule mod_authz_host.c>\nAllow from all\n</IfModule>\n</IfModule>\n<IfModule mod_access_compat>\nAllow from all\n</IfModule>\n";
+ $deny = "<IfModule mod_access.c>\nDeny from all\n</IfModule>\n<IfModule !mod_access_compat>\n<IfModule mod_authz_host.c>\nDeny from all\n</IfModule>\n</IfModule>\n<IfModule mod_access_compat>\nDeny from all\n</IfModule>\n";
+
+ // more selective allow/deny filters
+ $allowAny = "<Files \"*\">\n" . $allow . "Satisfy any\n</Files>\n";
+ $allowStaticAssets = "<Files ~ \"\\.(test\.php|gif|ico|jpg|png|svg|js|css|swf)$\">\n" . $allow . "Satisfy any\n</Files>\n";
+ $denyDirectPhp = "<Files ~ \"\\.(php|php4|php5|inc|tpl|in|twig)$\">\n" . $deny . "</Files>\n";
+
+ $directoriesToProtect = array(
+ '/js' => $allowAny,
+ '/libs' => $denyDirectPhp . $allowStaticAssets,
+ '/vendor' => $denyDirectPhp . $allowStaticAssets,
+ '/plugins' => $denyDirectPhp . $allowStaticAssets,
+ '/misc/user' => $denyDirectPhp . $allowStaticAssets,
+ );
+ foreach ($directoriesToProtect as $directoryToProtect => $content) {
+ Filesystem::createHtAccess(PIWIK_INCLUDE_PATH . $directoryToProtect, $overwrite = true, $content);
+ }
+ }
+
+ /**
+ * Generate IIS web.config files to restrict access
+ *
+ * Note: for IIS 7 and above
+ */
+ public static function createWebConfigFiles()
+ {
+ @file_put_contents(PIWIK_INCLUDE_PATH . '/web.config',
+ '<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+ <system.webServer>
+ <security>
+ <requestFiltering>
+ <hiddenSegments>
+ <add segment="config" />
+ <add segment="core" />
+ <add segment="lang" />
+ <add segment="tmp" />
+ </hiddenSegments>
+ <fileExtensions>
+ <add fileExtension=".tpl" allowed="false" />
+ <add fileExtension=".twig" allowed="false" />
+ <add fileExtension=".php4" allowed="false" />
+ <add fileExtension=".php5" allowed="false" />
+ <add fileExtension=".inc" allowed="false" />
+ <add fileExtension=".in" allowed="false" />
+ </fileExtensions>
+ </requestFiltering>
+ </security>
+ <directoryBrowse enabled="false" />
+ <defaultDocument>
+ <files>
+ <remove value="index.php" />
+ <add value="index.php" />
+ </files>
+ </defaultDocument>
+ </system.webServer>
+</configuration>');
+
+ // deny direct access to .php files
+ $directoriesToProtect = array(
+ '/libs',
+ '/vendor',
+ '/plugins',
+ );
+ foreach ($directoriesToProtect as $directoryToProtect) {
+ @file_put_contents(PIWIK_INCLUDE_PATH . $directoryToProtect . '/web.config',
+ '<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+ <system.webServer>
+ <security>
+ <requestFiltering>
+ <denyUrlSequences>
+ <add sequence=".php" />
+ </denyUrlSequences>
+ </requestFiltering>
+ </security>
+ </system.webServer>
+</configuration>');
+ }
+ }
+
+ /**
+ * Generate default robots.txt, favicon.ico, etc to suppress
+ * 404 (Not Found) errors in the web server logs, if Piwik
+ * is installed in the web root (or top level of subdomain).
+ *
+ * @see misc/crossdomain.xml
+ */
+ public static function createWebRootFiles()
+ {
+ $filesToCreate = array(
+ '/robots.txt',
+ '/favicon.ico',
+ );
+ foreach ($filesToCreate as $file) {
+ @file_put_contents(PIWIK_DOCUMENT_ROOT . $file, '');
+ }
+ }
+} \ No newline at end of file
diff --git a/plugins/LanguagesManager/API.php b/plugins/LanguagesManager/API.php
index eccb98050a..c7bee7603a 100644
--- a/plugins/LanguagesManager/API.php
+++ b/plugins/LanguagesManager/API.php
@@ -11,9 +11,10 @@
*/
namespace Piwik\Plugins\LanguagesManager;
-use Piwik\Piwik;
use Piwik\Common;
use Piwik\Db;
+use Piwik\Filesystem;
+use Piwik\Piwik;
/**
* The LanguagesManager API lets you access existing Piwik translations, and change Users languages preferences.
@@ -54,7 +55,7 @@ class API
public function isLanguageAvailable($languageCode)
{
return $languageCode !== false
- && Common::isValidFilename($languageCode)
+ && Filesystem::isValidFilename($languageCode)
&& in_array($languageCode, $this->getAvailableLanguages());
}
diff --git a/tests/PHPUnit/Core/CommonTest.php b/tests/PHPUnit/Core/CommonTest.php
index b0f69a69c4..e666ad9b5d 100644
--- a/tests/PHPUnit/Core/CommonTest.php
+++ b/tests/PHPUnit/Core/CommonTest.php
@@ -1,5 +1,6 @@
<?php
use Piwik\Common;
+use Piwik\Filesystem;
/**
* Piwik - Open source web analytics
@@ -383,7 +384,7 @@ class Core_CommonTest extends PHPUnit_Framework_TestCase
"test", "test.txt", "test.......", "en-ZHsimplified",
);
foreach ($valid as $toTest) {
- $this->assertTrue(Common::isValidFilename($toTest), $toTest . " not valid!");
+ $this->assertTrue(Filesystem::isValidFilename($toTest), $toTest . " not valid!");
}
}
@@ -398,7 +399,7 @@ class Core_CommonTest extends PHPUnit_Framework_TestCase
"../test", "/etc/htpasswd", '$var', ';test', '[bizarre]', '', ".htaccess", "very long long eogaioge ageja geau ghaeihieg heiagie aiughaeui hfilename",
);
foreach ($notvalid as $toTest) {
- $this->assertFalse(Common::isValidFilename($toTest), $toTest . " valid but shouldn't!");
+ $this->assertFalse(Filesystem::isValidFilename($toTest), $toTest . " valid but shouldn't!");
}
}
diff --git a/tests/PHPUnit/Core/PiwikTest.php b/tests/PHPUnit/Core/PiwikTest.php
index d9ae053b25..0da18e4fbf 100644
--- a/tests/PHPUnit/Core/PiwikTest.php
+++ b/tests/PHPUnit/Core/PiwikTest.php
@@ -5,8 +5,9 @@
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
-use Piwik\Piwik;
use Piwik\Access;
+use Piwik\Filesystem;
+use Piwik\Piwik;
use Piwik\Plugins\SitesManager\API;
use Piwik\Translate;
@@ -259,6 +260,6 @@ class PiwikTest extends DatabaseTestCase
*/
public function testCheckIfFileSystemIsNFSOnNonNFS()
{
- $this->assertFalse(Piwik::checkIfFileSystemIsNFS());
+ $this->assertFalse(Filesystem::checkIfFileSystemIsNFS());
}
}
diff --git a/tests/PHPUnit/Core/ReleaseCheckListTest.php b/tests/PHPUnit/Core/ReleaseCheckListTest.php
index a70cae6777..cdb12c3ca2 100644
--- a/tests/PHPUnit/Core/ReleaseCheckListTest.php
+++ b/tests/PHPUnit/Core/ReleaseCheckListTest.php
@@ -1,6 +1,6 @@
<?php
-use Piwik\Piwik;
use Piwik\Common;
+use Piwik\Filesystem;
use Piwik\Tracker\Db;
/**
@@ -57,7 +57,7 @@ class ReleaseCheckListTest extends PHPUnit_Framework_TestCase
public function testTemplatesDontContainDebug()
{
$patternFailIfFound = 'dump(';
- $files = Piwik::globr(PIWIK_INCLUDE_PATH . '/plugins', '*.twig');
+ $files = Filesystem::globr(PIWIK_INCLUDE_PATH . '/plugins', '*.twig');
foreach ($files as $file) {
$content = file_get_contents($file);
$this->assertFalse(strpos($content, $patternFailIfFound), 'found in ' . $file);
@@ -124,7 +124,7 @@ class ReleaseCheckListTest extends PHPUnit_Framework_TestCase
// SVN native does not make this work on windows
return;
}
- foreach (Piwik::globr(PIWIK_DOCUMENT_ROOT, '*') as $file) {
+ foreach (Filesystem::globr(PIWIK_DOCUMENT_ROOT, '*') as $file) {
// skip files in these folders
if (strpos($file, '/.git/') !== false ||
strpos($file, '/documentation/') !== false ||