This commit is contained in:
coderkun 2015-04-27 16:42:05 +02:00
commit 046a724272
4209 changed files with 1186656 additions and 0 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,315 @@
<?php
/**
* Piwik - Open source web analytics
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\Installation;
use Exception;
use HTML_QuickForm2_DataSource_Array;
use HTML_QuickForm2_Factory;
use HTML_QuickForm2_Rule;
use Piwik\Config;
use Piwik\Db\Adapter;
use Piwik\Db;
use Piwik\DbHelper;
use Piwik\Filesystem;
use Piwik\Piwik;
use Piwik\QuickForm2;
use Zend_Db_Adapter_Exception;
/**
*
*/
class FormDatabaseSetup extends QuickForm2
{
function __construct($id = 'databasesetupform', $method = 'post', $attributes = null, $trackSubmit = false)
{
parent::__construct($id, $method, $attributes = array('autocomplete' => 'off'), $trackSubmit);
}
function init()
{
HTML_QuickForm2_Factory::registerRule('checkValidFilename', 'Piwik\Plugins\Installation\FormDatabaseSetup_Rule_checkValidFilename');
$checkUserPrivilegesClass = 'Piwik\Plugins\Installation\Rule_checkUserPrivileges';
HTML_QuickForm2_Factory::registerRule('checkUserPrivileges', $checkUserPrivilegesClass);
$availableAdapters = Adapter::getAdapters();
$adapters = array();
foreach ($availableAdapters as $adapter => $port) {
$adapters[$adapter] = $adapter;
}
$this->addElement('text', 'host')
->setLabel(Piwik::translate('Installation_DatabaseSetupServer'))
->addRule('required', Piwik::translate('General_Required', Piwik::translate('Installation_DatabaseSetupServer')));
$user = $this->addElement('text', 'username')
->setLabel(Piwik::translate('Installation_DatabaseSetupLogin'));
$user->addRule('required', Piwik::translate('General_Required', Piwik::translate('Installation_DatabaseSetupLogin')));
$requiredPrivileges = Rule_checkUserPrivileges::getRequiredPrivilegesPretty();
$user->addRule('checkUserPrivileges',
Piwik::translate('Installation_InsufficientPrivilegesMain', $requiredPrivileges . '<br/><br/>') .
Piwik::translate('Installation_InsufficientPrivilegesHelp'));
$this->addElement('password', 'password')
->setLabel(Piwik::translate('General_Password'));
$item = $this->addElement('text', 'dbname')
->setLabel(Piwik::translate('Installation_DatabaseSetupDatabaseName'));
$item->addRule('required', Piwik::translate('General_Required', Piwik::translate('Installation_DatabaseSetupDatabaseName')));
$item->addRule('checkValidFilename', Piwik::translate('General_NotValid', Piwik::translate('Installation_DatabaseSetupDatabaseName')));
$this->addElement('text', 'tables_prefix')
->setLabel(Piwik::translate('Installation_DatabaseSetupTablePrefix'))
->addRule('checkValidFilename', Piwik::translate('General_NotValid', Piwik::translate('Installation_DatabaseSetupTablePrefix')));
$this->addElement('select', 'adapter')
->setLabel(Piwik::translate('Installation_DatabaseSetupAdapter'))
->loadOptions($adapters)
->addRule('required', Piwik::translate('General_Required', Piwik::translate('Installation_DatabaseSetupAdapter')));
$this->addElement('submit', 'submit', array('value' => Piwik::translate('General_Next') . ' »', 'class' => 'submit'));
// default values
$this->addDataSource(new HTML_QuickForm2_DataSource_Array(array(
'host' => '127.0.0.1',
'tables_prefix' => 'piwik_',
)));
}
/**
* Creates database object based on form data.
*
* @throws Exception|Zend_Db_Adapter_Exception
* @return array The database connection info. Can be passed into Piwik::createDatabaseObject.
*/
public function createDatabaseObject()
{
$dbname = $this->getSubmitValue('dbname');
if (empty($dbname)) // disallow database object creation w/ no selected database
{
throw new Exception("No database name");
}
$adapter = $this->getSubmitValue('adapter');
$port = Adapter::getDefaultPortForAdapter($adapter);
$dbInfos = array(
'host' => $this->getSubmitValue('host'),
'username' => $this->getSubmitValue('username'),
'password' => $this->getSubmitValue('password'),
'dbname' => $dbname,
'tables_prefix' => $this->getSubmitValue('tables_prefix'),
'adapter' => $adapter,
'port' => $port,
'schema' => Config::getInstance()->database['schema'],
'type' => Config::getInstance()->database['type']
);
if (($portIndex = strpos($dbInfos['host'], '/')) !== false) {
// unix_socket=/path/sock.n
$dbInfos['port'] = substr($dbInfos['host'], $portIndex);
$dbInfos['host'] = '';
} else if (($portIndex = strpos($dbInfos['host'], ':')) !== false) {
// host:port
$dbInfos['port'] = substr($dbInfos['host'], $portIndex + 1);
$dbInfos['host'] = substr($dbInfos['host'], 0, $portIndex);
}
try {
@Db::createDatabaseObject($dbInfos);
} catch (Zend_Db_Adapter_Exception $e) {
$db = Adapter::factory($adapter, $dbInfos, $connect = false);
// database not found, we try to create it
if ($db->isErrNo($e, '1049')) {
$dbInfosConnectOnly = $dbInfos;
$dbInfosConnectOnly['dbname'] = null;
@Db::createDatabaseObject($dbInfosConnectOnly);
@DbHelper::createDatabase($dbInfos['dbname']);
// select the newly created database
@Db::createDatabaseObject($dbInfos);
} else {
throw $e;
}
}
return $dbInfos;
}
}
/**
* Validation rule that checks that the supplied DB user has enough privileges.
*
* The following privileges are required for Piwik to run:
* - CREATE
* - ALTER
* - SELECT
* - INSERT
* - UPDATE
* - DELETE
* - DROP
* - CREATE TEMPORARY TABLES
*
*/
class Rule_checkUserPrivileges extends HTML_QuickForm2_Rule
{
const TEST_TABLE_NAME = 'piwik_test_table';
const TEST_TEMP_TABLE_NAME = 'piwik_test_table_temp';
/**
* Checks that the DB user entered in the form has the necessary privileges for Piwik
* to run.
*/
public function validateOwner()
{
// try and create the database object
try {
$this->createDatabaseObject();
} catch (Exception $ex) {
if ($this->isAccessDenied($ex)) {
return false;
} else {
return true; // if we can't create the database object, skip this validation
}
}
$db = Db::get();
try {
// try to drop tables before running privilege tests
$this->dropExtraTables($db);
} catch (Exception $ex) {
if ($this->isAccessDenied($ex)) {
return false;
} else {
throw $ex;
}
}
// check each required privilege by running a query that uses it
foreach (self::getRequiredPrivileges() as $privilegeType => $queries) {
if (!is_array($queries)) {
$queries = array($queries);
}
foreach ($queries as $sql) {
try {
if (in_array($privilegeType, array('SELECT'))) {
$db->fetchAll($sql);
} else {
$db->exec($sql);
}
} catch (Exception $ex) {
if ($this->isAccessDenied($ex)) {
return false;
} else {
throw new Exception("Test SQL failed to execute: $sql\nError: " . $ex->getMessage());
}
}
}
}
// remove extra tables that were created
$this->dropExtraTables($db);
return true;
}
/**
* Returns an array describing the database privileges required for Piwik to run. The
* array maps privilege names with one or more SQL queries that can be used to test
* if the current user has the privilege.
*
* NOTE: LOAD DATA INFILE & LOCK TABLES privileges are not **required** so they're
* not checked.
*
* @return array
*/
public static function getRequiredPrivileges()
{
return array(
'CREATE' => 'CREATE TABLE ' . self::TEST_TABLE_NAME . ' (
id INT AUTO_INCREMENT,
value INT,
PRIMARY KEY (id),
KEY index_value (value)
)',
'ALTER' => 'ALTER TABLE ' . self::TEST_TABLE_NAME . '
ADD COLUMN other_value INT DEFAULT 0',
'SELECT' => 'SELECT * FROM ' . self::TEST_TABLE_NAME,
'INSERT' => 'INSERT INTO ' . self::TEST_TABLE_NAME . ' (value) VALUES (123)',
'UPDATE' => 'UPDATE ' . self::TEST_TABLE_NAME . ' SET value = 456 WHERE id = 1',
'DELETE' => 'DELETE FROM ' . self::TEST_TABLE_NAME . ' WHERE id = 1',
'DROP' => 'DROP TABLE ' . self::TEST_TABLE_NAME,
'CREATE TEMPORARY TABLES' => 'CREATE TEMPORARY TABLE ' . self::TEST_TEMP_TABLE_NAME . ' (
id INT AUTO_INCREMENT,
PRIMARY KEY (id)
)',
);
}
/**
* Returns a string description of the database privileges required for Piwik to run.
*
* @return string
*/
public static function getRequiredPrivilegesPretty()
{
return implode('<br/>', array_keys(self::getRequiredPrivileges()));
}
/**
* Checks if an exception that was thrown after running a query represents an 'access denied'
* error.
*
* @param Exception $ex The exception to check.
* @return bool
*/
private function isAccessDenied($ex)
{
//NOte: this code is duplicated in Tracker.php error handler
return $ex->getCode() == 1044 || $ex->getCode() == 42000;
}
/**
* Creates a database object using the connection information entered in the form.
*
* @return array
*/
private function createDatabaseObject()
{
return $this->owner->getContainer()->createDatabaseObject();
}
/**
* Drops the tables created by the privilege checking queries, if they exist.
*
* @param \Piwik\Db $db The database object to use.
*/
private function dropExtraTables($db)
{
$db->query('DROP TABLE IF EXISTS ' . self::TEST_TABLE_NAME . ', ' . self::TEST_TEMP_TABLE_NAME);
}
}
/**
* Filename check for prefix/DB name
*
*/
class FormDatabaseSetup_Rule_checkValidFilename extends HTML_QuickForm2_Rule
{
function validateOwner()
{
$prefix = $this->owner->getValue();
return empty($prefix)
|| Filesystem::isValidFilename($prefix);
}
}

View file

@ -0,0 +1,89 @@
<?php
/**
* Piwik - Open source web analytics
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\Installation;
use HTML_QuickForm2_DataSource_Array;
use HTML_QuickForm2_Factory;
use HTML_QuickForm2_Rule;
use Piwik\Piwik;
use Piwik\Plugins\SitesManager\API;
use Piwik\QuickForm2;
/**
*
*/
class FormFirstWebsiteSetup extends QuickForm2
{
function __construct($id = 'websitesetupform', $method = 'post', $attributes = null, $trackSubmit = false)
{
parent::__construct($id, $method, $attributes, $trackSubmit);
}
function init()
{
HTML_QuickForm2_Factory::registerRule('checkTimezone', 'Piwik\Plugins\Installation\Rule_isValidTimezone');
$urlExample = 'http://example.org';
$javascriptOnClickUrlExample = "javascript:if(this.value=='$urlExample'){this.value='http://';} this.style.color='black';";
$timezones = API::getInstance()->getTimezonesList();
$timezones = array_merge(array('No timezone' => Piwik::translate('SitesManager_SelectACity')), $timezones);
$this->addElement('text', 'siteName')
->setLabel(Piwik::translate('Installation_SetupWebSiteName'))
->addRule('required', Piwik::translate('General_Required', Piwik::translate('Installation_SetupWebSiteName')));
$url = $this->addElement('text', 'url')
->setLabel(Piwik::translate('Installation_SetupWebSiteURL'));
$url->setAttribute('style', 'color:rgb(153, 153, 153);');
$url->setAttribute('onfocus', $javascriptOnClickUrlExample);
$url->setAttribute('onclick', $javascriptOnClickUrlExample);
$url->addRule('required', Piwik::translate('General_Required', Piwik::translate('Installation_SetupWebSiteURL')));
$tz = $this->addElement('select', 'timezone')
->setLabel(Piwik::translate('Installation_Timezone'))
->loadOptions($timezones);
$tz->addRule('required', Piwik::translate('General_Required', Piwik::translate('Installation_Timezone')));
$tz->addRule('checkTimezone', Piwik::translate('General_NotValid', Piwik::translate('Installation_Timezone')));
$tz = $this->addElement('select', 'ecommerce')
->setLabel(Piwik::translate('Goals_Ecommerce'))
->loadOptions(array(
0 => Piwik::translate('SitesManager_NotAnEcommerceSite'),
1 => Piwik::translate('SitesManager_EnableEcommerce'),
));
$this->addElement('submit', 'submit', array('value' => Piwik::translate('General_Next') . ' »', 'class' => 'submit'));
// default values
$this->addDataSource(new HTML_QuickForm2_DataSource_Array(array(
'url' => $urlExample,
)));
}
}
/**
* Timezone validation rule
*
*/
class Rule_isValidTimezone extends HTML_QuickForm2_Rule
{
function validateOwner()
{
try {
$timezone = $this->owner->getValue();
if (!empty($timezone)) {
API::getInstance()->setDefaultTimezone($timezone);
}
} catch (\Exception $e) {
return false;
}
return true;
}
}

View file

@ -0,0 +1,105 @@
<?php
/**
* Piwik - Open source web analytics
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\Installation;
use HTML_QuickForm2_DataSource_Array;
use HTML_QuickForm2_Factory;
use HTML_QuickForm2_Rule;
use Piwik\Piwik;
use Piwik\Plugins\UsersManager\UsersManager;
use Piwik\QuickForm2;
/**
*
*/
class FormGeneralSetup extends QuickForm2
{
function __construct($id = 'generalsetupform', $method = 'post', $attributes = null, $trackSubmit = false)
{
parent::__construct($id, $method, $attributes = array('autocomplete' => 'off'), $trackSubmit);
}
function init()
{
HTML_QuickForm2_Factory::registerRule('checkLogin', 'Piwik\Plugins\Installation\Rule_isValidLoginString');
HTML_QuickForm2_Factory::registerRule('checkEmail', 'Piwik\Plugins\Installation\Rule_isValidEmailString');
$login = $this->addElement('text', 'login')
->setLabel(Piwik::translate('Installation_SuperUserLogin'));
$login->addRule('required', Piwik::translate('General_Required', Piwik::translate('Installation_SuperUserLogin')));
$login->addRule('checkLogin');
$password = $this->addElement('password', 'password')
->setLabel(Piwik::translate('Installation_Password'));
$password->addRule('required', Piwik::translate('General_Required', Piwik::translate('Installation_Password')));
$pwMinLen = UsersManager::PASSWORD_MIN_LENGTH;
$pwMaxLen = UsersManager::PASSWORD_MAX_LENGTH;
$pwLenInvalidMessage = Piwik::translate('UsersManager_ExceptionInvalidPassword', array($pwMinLen, $pwMaxLen));
$password->addRule('length', $pwLenInvalidMessage, array('min' => $pwMinLen, 'max' => $pwMaxLen));
$passwordBis = $this->addElement('password', 'password_bis')
->setLabel(Piwik::translate('Installation_PasswordRepeat'));
$passwordBis->addRule('required', Piwik::translate('General_Required', Piwik::translate('Installation_PasswordRepeat')));
$passwordBis->addRule('eq', Piwik::translate('Installation_PasswordDoNotMatch'), $password);
$email = $this->addElement('text', 'email')
->setLabel(Piwik::translate('Installation_Email'));
$email->addRule('required', Piwik::translate('General_Required', Piwik::translate('Installation_Email')));
$email->addRule('checkEmail', Piwik::translate('UsersManager_ExceptionInvalidEmail'));
$this->addElement('checkbox', 'subscribe_newsletter_security', null, array(
'content' => '&nbsp;&nbsp;' . Piwik::translate('Installation_SecurityNewsletter'),
));
$this->addElement('checkbox', 'subscribe_newsletter_community', null, array(
'content' => '&nbsp;&nbsp;' . Piwik::translate('Installation_CommunityNewsletter'),
));
$this->addElement('submit', 'submit', array('value' => Piwik::translate('General_Next') . ' »', 'class' => 'submit'));
// default values
$this->addDataSource(new HTML_QuickForm2_DataSource_Array(array(
'subscribe_newsletter_community' => 1,
'subscribe_newsletter_security' => 1,
)));
}
}
/**
* Login id validation rule
*
*/
class Rule_isValidLoginString extends HTML_QuickForm2_Rule
{
function validateOwner()
{
try {
$login = $this->owner->getValue();
if (!empty($login)) {
Piwik::checkValidLoginString($login);
}
} catch (\Exception $e) {
$this->setMessage($e->getMessage());
return false;
}
return true;
}
}
/**
* Email address validation rule
*
*/
class Rule_isValidEmailString extends HTML_QuickForm2_Rule
{
function validateOwner()
{
return Piwik::isValidEmailString($this->owner->getValue());
}
}

View file

@ -0,0 +1,122 @@
<?php
/**
* Piwik - Open source web analytics
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\Installation;
use Piwik\Common;
use Piwik\Config;
use Piwik\FrontController;
use Piwik\Menu\MenuAdmin;
use Piwik\Piwik;
use Piwik\Translate;
/**
*
*/
class Installation extends \Piwik\Plugin
{
protected $installationControllerName = '\\Piwik\\Plugins\\Installation\\Controller';
/**
* @see Piwik\Plugin::getListHooksRegistered
*/
public function getListHooksRegistered()
{
$hooks = array(
'Config.NoConfigurationFile' => 'dispatch',
'Config.badConfigurationFile' => 'dispatch',
'Request.dispatch' => 'dispatchIfNotInstalledYet',
'Menu.Admin.addItems' => 'addMenu',
'AssetManager.getStylesheetFiles' => 'getStylesheetFiles',
);
return $hooks;
}
public function dispatchIfNotInstalledYet(&$module, &$action, &$parameters)
{
$general = Config::getInstance()->General;
if (empty($general['installation_in_progress'])) {
return;
}
if ($module == 'Installation') {
return;
}
$module = 'Installation';
if (!$this->isAllowedAction($action)) {
$action = 'welcome';
}
$parameters = array();
}
public function setControllerToLoad($newControllerName)
{
$this->installationControllerName = $newControllerName;
}
protected function getInstallationController()
{
return new $this->installationControllerName();
}
/**
* @param \Exception|null $exception
*/
public function dispatch($exception = null)
{
if ($exception) {
$message = $exception->getMessage();
} else {
$message = '';
}
Translate::loadCoreTranslation();
$action = Common::getRequestVar('action', 'welcome', 'string');
if ($this->isAllowedAction($action)) {
echo FrontController::getInstance()->dispatch('Installation', $action, array($message));
} else {
Piwik::exitWithErrorMessage(Piwik::translate('Installation_NoConfigFound'));
}
exit;
}
/**
* Adds the 'System Check' admin page if the user is the Super User.
*/
public function addMenu()
{
MenuAdmin::addEntry('Installation_SystemCheck',
array('module' => 'Installation', 'action' => 'systemCheckPage'),
Piwik::hasUserSuperUserAccess(),
$order = 15);
}
/**
* Adds CSS files to list of CSS files for asset manager.
*/
public function getStylesheetFiles(&$stylesheets)
{
$stylesheets[] = "plugins/Installation/stylesheets/systemCheckPage.less";
}
private function isAllowedAction($action)
{
$controller = $this->getInstallationController();
$isActionWhiteListed = in_array($action, array('saveLanguage', 'getBaseCss', 'reuseTables'));
return in_array($action, array_keys($controller->getInstallationSteps()))
|| $isActionWhiteListed;
}
}

View file

@ -0,0 +1,132 @@
<?php
/**
* Piwik - Open source web analytics
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
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\nRequire all granted\n</IfModule>\n<IfModule !mod_access_compat>\n<IfModule mod_authz_host.c>\nAllow from all\nRequire all granted\n</IfModule>\n</IfModule>\n<IfModule mod_access_compat>\nAllow from all\nRequire all granted\n</IfModule>\n";
$deny = "<IfModule mod_access.c>\nDeny from all\nRequire all denied\n</IfModule>\n<IfModule !mod_access_compat>\n<IfModule mod_authz_host.c>\nDeny from all\nRequire all denied\n</IfModule>\n</IfModule>\n<IfModule mod_access_compat>\nDeny from all\nRequire all denied\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, '');
}
}
}

View file

@ -0,0 +1,51 @@
<?php
/**
* Piwik - Open source web analytics
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\Installation;
/**
*
*/
class View extends \Piwik\View
{
public function __construct($subtemplatePath, $installationSteps, $currentStepName)
{
parent::__construct($subtemplatePath);
$this->steps = array_keys($installationSteps);
$this->allStepsTitle = array_values($installationSteps);
$this->currentStepName = $currentStepName;
$this->showNextStep = false;
}
public function render()
{
// prepare the all steps templates
$this->currentStepId = array_search($this->currentStepName, $this->steps);
$this->totalNumberOfSteps = count($this->steps);
$this->percentDone = round(($this->currentStepId) * 100 / ($this->totalNumberOfSteps - 1));
$this->percentToDo = 100 - $this->percentDone;
$this->nextModuleName = '';
if (isset($this->steps[$this->currentStepId + 1])) {
$this->nextModuleName = $this->steps[$this->currentStepId + 1];
}
$this->previousModuleName = '';
if (isset($this->steps[$this->currentStepId - 1])) {
$this->previousModuleName = $this->steps[$this->currentStepId - 1];
}
$this->previousPreviousModuleName = '';
if (isset($this->steps[$this->currentStepId - 2])) {
$this->previousPreviousModuleName = $this->steps[$this->currentStepId - 2];
}
return parent::render();
}
}

View file

@ -0,0 +1,8 @@
$(function () {
$('#toFade').fadeOut(4000, function () { $(this).show().css({visibility: 'hidden'}); });
$('input:first').focus();
$('#progressbar').progressbar({
value: parseInt($('#progressbar').attr('data-progress'))
});
$('code').click(function () { $(this).select(); });
});

View file

@ -0,0 +1,250 @@
div.both {
clear: both;
}
body {
background-color: #FFFBF9;
text-align: center;
font-family: Arial, Georgia, "Times New Roman", Times, serif;
font-size: 17px;
}
p {
margin-bottom: 5px;
margin-top: 10px;
}
#title {
font-size: 50px;
color: #284F92;
vertical-align: text-bottom;
}
#subtitle {
color: #666;
font-size: 27px;
padding-left: 20px;
vertical-align: sub;
}
#logo {
padding: 20px 30px;
padding-bottom: 35px;
}
#logo img {
height:40px;
}
#installationPage #logo {
height: auto;
}
h2 {
font-size: 20px;
color: #666666;
border-bottom: 1px solid #DADADA;
padding: 0 0 7px;
}
h3 {
margin-top: 10px;
font-size: 17px;
color: #3F5163;
}
code {
font-size: 80%;
}
.topBarElem {
font-family: arial, sans-serif !important;
font-size: 13px;
line-height: 1.33;
}
#topRightBar {
float: right;
margin-top: -60px;
}
.error {
color: red;
font-size: 100%;
font-weight: bold;
border: 2px solid red;
width: 550px;
padding: 20px;
margin-bottom: 10px;
}
.error img {
border: 0;
float: right;
margin: 10px;
}
.success {
color: #26981C;
font-size: 130%;
font-weight: bold;
padding: 10px;
}
.warn {
color: #D7A006;
font-weight: bold;
}
.warning {
margin: 10px;
color: #ff5502;
font-size: 130%;
font-weight: bold;
padding: 10px 20px 10px 30px;
border: 1px solid #ff5502;
}
.warning ul {
list-style: disc;
}
.success img, .warning img {
border: 0;
vertical-align: bottom;
}
/* Cadre general */
#installationPage {
margin: 30px 5px 5px;
text-align: left;
}
#content {
font-size: 90%;
line-height: 1.4em;
width: 860px;
border: 1px solid #7A5A3F;
margin: auto;
background: #FFFFFF;
padding: 0.2em 2em 2em 2em;
border-radius: 8px;
}
/* form errors */
#adminErrors {
color: #FF6E46;
font-size: 120%;
}
/* listing all the steps */
#generalInstall {
float: left;
margin-left: 20px;
width: 19%;
}
#detailInstall {
width: 75%;
float: right;
}
#generalInstall ul {
list-style-type: decimal;
}
li.futureStep {
color: #d3d3d3;
}
li.actualStep {
font-weight: bold;
}
li.pastStep {
color: #008000;
}
p.nextStep a {
text-decoration: none;
}
td {
border: 1px solid rgb(198, 205, 216);
border-top-color: #FFF;
color: #444;
padding: 0.5em 0.5em 0.5em 0.8em;
}
.submit {
text-align: center;
cursor: pointer;
margin-top: 10px;
}
.submit input {
margin-top: 15px;
background: transparent url(../../../plugins/Zeitgeist/images/background-submit.png) repeat scroll 0;
font-size: 1.4em;
border-color: #CCCCCC rgb(153, 153, 153) rgb(153, 153, 153) rgb(204, 204, 204);
border-style: double;
border-width: 3px;
color: #333333;
padding: 0.15em;
}
input {
font-size: 18px;
border-color: #CCCCCC rgb(153, 153, 153) rgb(153, 153, 153) rgb(204, 204, 204);
border-width: 1px;
color: #3A2B16;
padding: 0.15em;
}
#systemCheckLegend {
border: 1px solid #A5A5A5;
padding: 20px;
color: #727272;
margin-top: 30px;
}
#systemCheckLegend img {
padding-right: 10px;
vertical-align: middle;
}
.reuseTables .error {
margin: 10px 0px;
}
.reuseTables .warning {
color: #ff5502;
font-size: 100%;
font-weight: bold;
padding: 20px;
border: 2px solid #ff5502;
width: 550px;
margin: 10px 0px;
}
.reuseTables .warning img {
border: 0;
float: right;
margin: 10px;
}
.reuseTables ul {
padding-left: 16px;
list-style: disc;
}
.infos img, .infosServer img {
padding-right: 10px;
vertical-align: middle;
}
.err {
color: red;
font-weight: bold;
}

View file

@ -0,0 +1,45 @@
#systemCheckOptional,
#systemCheckRequired {
border: 1px solid #dadada;
width: 100%;
max-width: 900px;
}
#systemCheckOptional {
margin-bottom: 2em;
}
#systemCheckOptional td,
#systemCheckRequired td {
padding: 1em .5em 1em 2em;
vertical-align: middle;
font-size: 1.2em;
margin: 0;
}
#systemCheckOptional tr:nth-child(even),
#systemCheckRequired tr:nth-child(even) {
background-color: #EFEEEC;
}
#systemCheckOptional tr:nth-child(odd),
#systemCheckRequired tr:nth-child(odd) {
background-color: #F6F5F3;
}
.error {
color: red;
font-size: 100%;
font-weight: bold;
border: 2px solid red;
width: 550px;
padding: 20px;
margin-bottom: 10px;
}
.error img {
border: 0;
float: right;
margin: 10px;
}

View file

@ -0,0 +1,11 @@
<ul>
{% for stepId,stepName in allStepsTitle %}
{% if currentStepId > stepId %}
<li class="pastStep">{{ stepName|translate }}</li>
{% elseif currentStepId == stepId %}
<li class="actualStep">{{ stepName|translate }}</li>
{% else %}
<li class="futureStep">{{ stepName|translate }}</li>
{% endif %}
{% endfor %}
</ul>

View file

@ -0,0 +1,40 @@
{% if warningMessages is not defined %}
{% set warningMessages=infos.integrityErrorMessages %}
{% endif %}
<div id="integrity-results" title="{{ 'Installation_SystemCheckFileIntegrity'|translate }}" style="display:none; font-size: 62.5%;">
<table>
{% for msg in warningMessages %}
<tr>
<td>{{ msg }}</td>
</tr>
{% endfor %}
</table>
</div>
<script type="text/javascript">
<!--
$(function () {
$("#integrity-results").dialog({
modal: true,
autoOpen: false,
width: 600,
buttons: {
Ok: function () {
$(this).dialog('close');
}
}
});
});
$('#more-results').click(function () {
$('#integrity-results').dialog('open');
}).hover(function () {
$(this).addClass("ui-state-hover");
},
function () {
$(this).removeClass("ui-state-hover");
}).mousedown(function () {
$(this).addClass("ui-state-active");
}).mouseup(function () {
$(this).removeClass("ui-state-active");
});
//-->
</script>

View file

@ -0,0 +1,15 @@
<div id="systemCheckLegend">
<span style="font-size: small;">
<h2>{{ 'Installation_Legend'|translate }}</h2>
<br/>
<img src='plugins/Zeitgeist/images/warning.png'/> <span class="warn">{{ 'General_Warning'|translate }}: {{ 'Installation_SystemCheckWarning'|translate }}</span>
<br/>
<img src='plugins/Zeitgeist/images/error.png'/> <span style="color:red;font-weight:bold;">{{ 'General_Error'|translate }}
: {{ 'Installation_SystemCheckError'|translate }} </span><br/>
<img src='plugins/Zeitgeist/images/ok.png'/> <span style="color:#26981C;font-weight:bold;">{{ 'General_Ok'|translate }}</span><br/>
</span>
</div>
<p class="nextStep">
<a href="{{ url }}">{{ 'General_RefreshPage'|translate }} &raquo;</a>
</p>

View file

@ -0,0 +1,329 @@
{% set ok %}<img src='plugins/Zeitgeist/images/ok.png' />{% endset %}
{% set error %}<img src='plugins/Zeitgeist/images/error.png' />{% endset %}
{% set warning %}<img src='plugins/Zeitgeist/images/warning.png' />{% endset %}
{% set link %}<img src='plugins/Zeitgeist/images/link.gif' />{% endset %}
<table class="infosServer" id="systemCheckRequired">
<tr>
{% set MinPHP %}{{ 'Installation_SystemCheckPhp'|translate }} &gt; {{ infos.phpVersion_minimum }}{% endset %}
<td class="label">{{ MinPHP }}</td>
<td>
{% if infos.phpVersion_ok %}
{{ ok }}
{% else %}
{{ error }} <span class="err">{{ 'General_Error'|translate }}: {{ 'General_Required'|translate(MinPHP)|raw }}</span>
{% endif %}
</td>
</tr>
<tr>
<td class="label">PDO {{ 'Installation_Extension'|translate }}</td>
<td>
{% if infos.pdo_ok %}
{{- ok -}}
{% else %}
-
{% endif %}
</td>
</tr>
{% for adapter, port in infos.adapters %}
<tr>
<td class="label">{{ adapter }} {{ 'Installation_Extension'|translate }}</td>
<td>{{ ok }}</td>
</tr>
{% endfor %}
{% if infos.adapters|length == 0 %}
<tr>
<td colspan="2" class="error" style="font-size: small;">
{{ 'Installation_SystemCheckDatabaseHelp'|translate }}
<p>
{% if infos.isWindows %}
{{ 'Installation_SystemCheckWinPdoAndMysqliHelp'|translate("<br /><br /><code>extension=php_mysqli.dll</code><br /><code>extension=php_pdo.dll</code><br /><code>extension=php_pdo_mysql.dll</code><br />")|raw|nl2br }}
{% else %}
{{ 'Installation_SystemCheckPdoAndMysqliHelp'|translate("<br /><br /><code>--with-mysqli</code><br /><code>--with-pdo-mysql</code><br /><br />","<br /><br /><code>extension=mysqli.so</code><br /><code>extension=pdo.so</code><br /><code>extension=pdo_mysql.so</code><br />")|raw }}
{% endif %}
{{ 'Installation_RestartWebServer'|translate }}
<br/>
<br/>
{{ 'Installation_SystemCheckPhpPdoAndMysqli'|translate("<a style=\"color:red\" href=\"http:\/\/php.net\/pdo\">","<\/a>","<a style=\"color:red\" href=\"http:\/\/php.net\/mysqli\">","<\/a>")|raw|nl2br }}
</p>
</td>
</tr>
{% endif %}
<tr>
<td class="label">{{ 'Installation_SystemCheckExtensions'|translate }}</td>
<td>
{% for needed_extension in infos.needed_extensions %}
{% if needed_extension in infos.missing_extensions %}
{{ error }}
{% set hasError %}1{% endset %}
{% else %}
{{ ok }}
{% endif %}
{{ needed_extension }}
<br/>
{% endfor %}
<br/>{% if hasError is defined %}{{ 'Installation_RestartWebServer'|translate }}{% endif %}
</td>
</tr>
{% if infos.missing_extensions|length > 0 %}
<tr>
<td colspan="2" class="error" style="font-size: small;">
{% for missing_extension in infos.missing_extensions %}
<p>
<em>{{ helpMessages[missing_extension]|translate }}</em>
</p>
{% endfor %}
</td>
</tr>
{% endif %}
<tr>
<td class="label">{{ 'Installation_SystemCheckFunctions'|translate }}</td>
<td>
{% for needed_function in infos.needed_functions %}
{% if needed_function in infos.missing_functions %}
{{ error }}
<span class='err'>{{ needed_function }}</span>
{% set hasError %}1{% endset %}
<p>
<em>{{ helpMessages[needed_function]|translate }}</em>
</p>
{% else %}
{{ ok }} {{ needed_function }}
<br/>
{% endif %}
{% endfor %}
<br/>{% if hasError is defined %}{{ 'Installation_RestartWebServer'|translate }}{% endif %}
</td>
</tr>
<tr>
<td valign="top">
{{ 'Installation_SystemCheckWriteDirs'|translate }}
</td>
<td style="font-size: small;">
{% for dir, bool in infos.directories %}
{% if bool %}
{{ ok }}
{% else %}
<span style="color:red;">{{ error }}</span>
{% endif %}
{{ dir }}
<br/>
{% endfor %}
</td>
</tr>
{% if problemWithSomeDirectories %}
<tr>
<td colspan="2" class="error">
{{ 'Installation_SystemCheckWriteDirsHelp'|translate }}:
{% for dir,bool in infos.directories %}
<ul>
{% if not bool %}
<li>
<pre>chmod a+w {{ dir }}</pre>
</li>
{% endif %}
</ul>
{% endfor %}
</td>
</tr>
{% endif %}
</table>
<br/>
<h2>{{ 'Installation_Optional'|translate }}</h2>
<table class="infos" id="systemCheckOptional">
<tr>
<td class="label">{{ 'Installation_SystemCheckFileIntegrity'|translate }}</td>
<td>
{% if infos.integrityErrorMessages is empty %}
{{ ok }}
{% else %}
{% if infos.integrity %}
{{ warning }}
<em>{{ infos.integrityErrorMessages[0] }}</em>
{% else %}
{{ error }}
<em>{{ infos.integrityErrorMessages[0] }}</em>
{% endif %}
{% if infos.integrityErrorMessages|length > 1 %}
<button id="more-results" class="ui-button ui-state-default ui-corner-all">{{ 'General_Details'|translate }}</button>
{% endif %}
{% endif %}
</td>
</tr>
<tr>
<td class="label">{{ 'Installation_SystemCheckTracker'|translate }}</td>
<td>
{% if infos.tracker_status == 0 %}
{{ ok }}
{% else %}
{{ warning }}
<span class="warn">{{ infos.tracker_status }}
<br/>{{ 'Installation_SystemCheckTrackerHelp'|translate }} </span>
<br/>
{{ 'Installation_RestartWebServer'|translate }}
{% endif %}
</td>
</tr>
<tr>
<td class="label">{{ 'Installation_SystemCheckMemoryLimit'|translate }}</td>
<td>
{% if infos.memory_ok %}
{{ ok }} {{ infos.memoryCurrent }}
{% else %}
{{ warning }}
<span class="warn">{{ infos.memoryCurrent }}</span>
<br/>
{{ 'Installation_SystemCheckMemoryLimitHelp'|translate }}
{{ 'Installation_RestartWebServer'|translate }}
{% endif %}
</td>
</tr>
<tr>
<td class="label">{{ 'SitesManager_Timezone'|translate }}</td>
<td>
{% if infos.timezone %}
{{ ok }}
{% else %}
{{ warning }}
<span class="warn">{{ 'SitesManager_AdvancedTimezoneSupportNotFound'|translate }} </span>
<br/>
<a href="http://php.net/manual/en/datetime.installation.php" target="_blank">Timezone PHP documentation</a>
.
{% endif %}
</td>
</tr>
<tr>
<td class="label">{{ 'Installation_SystemCheckOpenURL'|translate }}</td>
<td>
{% if infos.openurl %}
{{ ok }} {{ infos.openurl }}
{% else %}
{{ warning }}
<span class="warn">{{ 'Installation_SystemCheckOpenURLHelp'|translate }}</span>
{% endif %}
{% if not infos.can_auto_update %}
<br/>
{{ warning }} <span class="warn">{{ 'Installation_SystemCheckAutoUpdateHelp'|translate }}</span>
{% endif %}
</td>
</tr>
<tr>
<td class="label">{{ 'Installation_SystemCheckGDFreeType'|translate }}</td>
<td>
{% if infos.gd_ok %}
{{ ok }}
{% else %}
{{ warning }} <span class="warn">{{ 'Installation_SystemCheckGDFreeType'|translate }}
<br/>
{{ 'Installation_SystemCheckGDHelp'|translate }} </span>
{% endif %}
</td>
</tr>
<tr>
<td class="label">{{ 'Installation_SystemCheckOtherExtensions'|translate }}</td>
<td>
{% for desired_extension in infos.desired_extensions %}
{% if desired_extension in infos.missing_desired_extensions %}
{{ warning }}<span class="warn">{{ desired_extension }}</span>
<p>{{ helpMessages[desired_extension]|translate }}</p>
{% else %}
{{ ok }} {{ desired_extension }}
<br/>
{% endif %}
{% endfor %}
</td>
</tr>
<tr>
<td class="label">{{ 'Installation_SystemCheckOtherFunctions'|translate }}</td>
<td>
{% for desired_function in infos.desired_functions %}
{% if desired_function in infos.missing_desired_functions %}
{{ warning }}
<span class="warn">{{ desired_function }}</span>
<p>{{ helpMessages[desired_function]|translate }}</p>
{% else %}
{{ ok }} {{ desired_function }}
<br/>
{% endif %}
{% endfor %}
</td>
</tr>
<tr>
<td class="label">{{ 'Installation_Filesystem'|translate }}</td>
<td>
{% if not infos.is_nfs %}
{{ ok }} {{ 'General_Ok'|translate }}
<br/>
{% else %}
{{ warning }}
<span class="warn">{{ 'Installation_NfsFilesystemWarning'|translate }}</span>
{% if duringInstall is not empty %}
<p>{{ 'Installation_NfsFilesystemWarningSuffixInstall'|translate }}</p>
{% else %}
<p>{{ 'Installation_NfsFilesystemWarningSuffixAdmin'|translate }}</p>
{% endif %}
{% endif %}
</td>
</tr>
{% if duringInstall is empty %}
<tr>
<td class="label">{{ 'UserCountry_Geolocation'|translate }}</td>
<td>
{% if infos.extra.geolocation_ok %}
{{ ok }} {{ 'General_Ok'|translate }}
<br/>
{% elseif infos.extra.geolocation_using_non_recommended %}
{{ warning }}
<span class="warn">{{ 'UserCountry_GeoIpLocationProviderNotRecomnended'|translate }}
{{ 'UserCountry_GeoIpLocationProviderDesc_ServerBased2'|translate('<a href="http://piwik.org/docs/geo-locate/" target="_blank">', '', '', '</a>')|raw }}</span>
<br/>
{% else %}
{{ warning }}
<span class="warn">{{ 'UserCountry_DefaultLocationProviderDesc1'|translate }}
{{ 'UserCountry_DefaultLocationProviderDesc2'|translate('<a href="http://piwik.org/docs/geo-locate/" target="_blank">', '', '', '</a>')|raw }} </span>
</span>
{% endif %}
</td>
</tr>
{% endif %}
{% if infos.general_infos.assume_secure_protocol is defined %}
<tr>
<td class="label">{{ 'Installation_SystemCheckSecureProtocol'|translate }}</td>
<td>
{{ warning }} <span class="warn">{{ infos.protocol }} </span><br/>
{{ 'Installation_SystemCheckSecureProtocolHelp'|translate }}
<br/><br/>
<code>[General]<br/>
assume_secure_protocol = 1</code><br/>
</td>
</tr>
{% endif %}
{% if infos.extra.load_data_infile_available is defined %}
<tr>
<td class="label">{{ 'Installation_DatabaseAbilities'|translate }}</td>
<td>
{% if infos.extra.load_data_infile_available %}
{{ ok }} LOAD DATA INFILE
<br/>
{% else %}
{{ warning }}
<span class="warn">LOAD DATA INFILE</span>
<br/>
<br/>
<p>{{ 'Installation_LoadDataInfileUnavailableHelp'|translate("LOAD DATA INFILE","FILE") }}</p>
<p>{{ 'Installation_LoadDataInfileRecommended'|translate }}</p>
{% if infos.extra.load_data_infile_error is defined %}
<em><strong>{{ 'General_Error'|translate }}:</strong></em>
{{ infos.extra.load_data_infile_error|raw }}
{% endif %}
<p>Troubleshooting: <a target='_blank' href="?module=Proxy&action=redirect&url=http://piwik.org/faq/troubleshooting/%23faq_194">FAQ on piwik.org</a></p>
{% endif %}
</td>
</tr>
{% endif %}
</table>
{% include "@Installation/_integrityDetails.twig" %}

View file

@ -0,0 +1,36 @@
{% extends '@Installation/layout.twig' %}
{% block content %}
{% set ok %}<img src='plugins/Zeitgeist/images/ok.png' />{% endset %}
{% set error %}<img src='plugins/Zeitgeist/images/error.png' />{% endset %}
{% set warning %}<img src='plugins/Zeitgeist/images/warning.png' />{% endset %}
{% set link %}<img src='plugins/Zeitgeist/images/link.gif' />{% endset %}
<h2>{{ 'Installation_DatabaseCheck'|translate }}</h2>
<table class="infosServer">
<tr>
<td class="label">{{ 'Installation_DatabaseServerVersion'|translate }}</td>
<td>{% if databaseVersionOk is defined %}{{ ok }}{% else %}{{ error }}{% endif %}</td>
</tr>
<tr>
<td class="label">{{ 'Installation_DatabaseClientVersion'|translate }}</td>
<td>{% if clientVersionWarning is defined %}{{ warning }}{% else %}{{ ok }}{% endif %}</td>
</tr>
{% if clientVersionWarning is defined %}
<tr>
<td colspan="2">
<span style="font-size: small;color:#FF7F00;">{{ clientVersionWarning }}</span>
</td>
</tr>
{% endif %}
<tr>
<td class="label">{{ 'Installation_DatabaseCreation'|translate }}</td>
<td>{% if databaseCreated is defined %}{{ ok }}{% else %}{{ error }}{% endif %}</td>
</tr>
</table>
<p>
{{ link }} <a href="?module=Proxy&action=redirect&url=http://piwik.org/docs/requirements/" target="_blank">{{ 'Installation_Requirements'|translate }}</a>
</p>
{% endblock %}

View file

@ -0,0 +1,18 @@
{% extends '@Installation/layout.twig' %}
{% block content %}
<h2>{{ 'Installation_DatabaseSetup'|translate }}</h2>
{% if errorMessage is defined %}
<div class="error">
<img src="plugins/Zeitgeist/images/error_medium.png"/>
{{ 'Installation_DatabaseErrorConnect'|translate }}:
<br/>{{ errorMessage|raw }}
</div>
{% endif %}
{% if form_data is defined %}
{% include "genericForm.twig" %}
{% endif %}
{% endblock %}

View file

@ -0,0 +1,24 @@
{% extends '@Installation/layout.twig' %}
{% block content %}
<h2>{{ 'Installation_Congratulations'|translate|raw }}</h2>
{{ 'Installation_CongratulationsHelp'|translate|raw }}
<br/>
<h2>{{ 'Installation_WelcomeToCommunity'|translate }}</h2>
<p>
{{ 'Installation_CollaborativeProject'|translate }}
</p><p>
{{ 'Installation_GetInvolved'|translate('<a target="_blank" href="http://piwik.org/get-involved/">','</a>')|raw }}
{{ 'General_HelpTranslatePiwik'|translate("<a target='_blank' href=\'http://piwik.org/translations/\'>","<\/a>")|raw }}
</p>
<p>{{ 'Installation_WeHopeYouWillEnjoyPiwik'|translate }}</p>
<p><i>{{ 'Installation_HappyAnalysing'|translate }}</i></p>
<p class="nextStep">
<a class="submit" href="index.php">{{ 'General_ContinueToPiwik'|translate }} &raquo;</a>
</p>
{% endblock %}

View file

@ -0,0 +1,27 @@
{% extends '@Installation/layout.twig' %}
{% block content %}
{% if displayGeneralSetupSuccess is defined %}
<span id="toFade" class="success">
{{ 'Installation_SuperUserSetupSuccess'|translate }}
<img src="plugins/Zeitgeist/images/success_medium.png"/>
</span>
{% endif %}
<h2>{{ 'Installation_SetupWebsite'|translate }}</h2>
<p>{{ 'Installation_SiteSetup'|translate }}</p>
{% if errorMessage is defined %}
<div class="error">
<img src="plugins/Zeitgeist/images/error_medium.png"/>
{{ 'Installation_SetupWebsiteError'|translate }}:
<br/>- {{ errorMessage|raw }}
</div>
{% endif %}
{% if form_data is defined %}
{% include "genericForm.twig" %}
{% endif %}
<br/>
<p><em>{{ 'Installation_SiteSetupFootnote'|translate }}</em></p>
{% endblock %}

View file

@ -0,0 +1,18 @@
{% extends '@Installation/layout.twig' %}
{% block content %}
<h2>{{ 'Installation_SuperUser'|translate }}</h2>
{% if errorMessage is defined %}
<div class="error">
<img src="plugins/Zeitgeist/images/error_medium.png"/>
{{ 'Installation_SuperUserSetupError'|translate }}:
<br/>- {{ errorMessage|raw }}
</div>
{% endif %}
{% if form_data is defined %}
{% include "genericForm.twig" %}
{% endif %}
{% endblock %}

View file

@ -0,0 +1,62 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Piwik &rsaquo; {{ 'Installation_Installation'|translate }}</title>
<link rel="stylesheet" type="text/css" href="libs/jquery/themes/base/jquery-ui.css"/>
<link rel="stylesheet" type="text/css" href="index.php?module=Installation&action=getBaseCss"/>
<link rel="shortcut icon" href="plugins/CoreHome/images/favicon.ico"/>
<script type="text/javascript" src="libs/jquery/jquery.js"></script>
<script type="text/javascript" src="libs/jquery/jquery-ui.js"></script>
<script type="text/javascript" src="plugins/Installation/javascripts/installation.js"></script>
<link rel="stylesheet" type="text/css" href="plugins/Installation/stylesheets/installation.css"/>
{% if 'General_LayoutDirection'|translate =='rtl' %}
<link rel="stylesheet" type="text/css" href="plugins/Zeitgeist/stylesheets/rtl.css"/>
{% endif %}
</head>
<body>
<div id="installationPage">
<div id="content">
<div id="logo">
<img id="title" src="plugins/Morpheus/images/logo.png"/> &nbsp;&nbsp;&nbsp;<span
id="subtitle"># {{ 'General_OpenSourceWebAnalytics'|translate }}</span>
</div>
<div style="float:right;" id="topRightBar">
<br/>
{{ postEvent('Template.topBar')|raw }}
</div>
<div class="both"></div>
<div id="generalInstall">
{% include "@Installation/_allSteps.twig" %}
</div>
<div id="detailInstall">
{% set nextButton %}
<p class="nextStep">
<a class="submit" href="{{ linkTo({'action':nextModuleName, 'token_auth':null, 'method':null }) }}">{{ 'General_Next'|translate }} &raquo;</a>
</p>
{% endset %}
{% if showNextStepAtTop is defined and showNextStepAtTop %}
{{ nextButton }}
{% endif %}
{% block content %}{% endblock %}
{% if showNextStep %}
{{ nextButton }}
{% endif %}
</div>
<div class="both"></div>
<br/>
<br/>
<h3>{{ 'Installation_InstallationStatus'|translate }}</h3>
<div id="progressbar" data-progress="{{ percentDone }}"></div>
{{ 'Installation_PercentDone'|translate(percentDone) }}
</div>
</div>
</body>
</html>

View file

@ -0,0 +1,81 @@
{% extends '@Installation/layout.twig' %}
{% block content %}
{% set helpMessage %}{{- 'CoreUpdater_HelpMessageContent'|translate('[',']',"<br/>")|raw }}{% endset %}
<h2>{{ 'Installation_ReusingTables'|translate }}</h2>
<div class="reuseTables">
{% if coreError %}
<div class="error">
<img src="plugins/Zeitgeist/images/error_medium.png"/> {{ 'CoreUpdater_CriticalErrorDuringTheUpgradeProcess'|translate }}
<ul>
{% for message in errorMessages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
</div>
<p>{{ 'CoreUpdater_HelpMessageIntroductionWhenError'|translate }}
<ul>
<li>{{ helpMessage }}</li>
</ul>
</p>
<p>{{ 'CoreUpdater_ErrorDIYHelp'|translate }}
<ul>
<li>{{ 'CoreUpdater_ErrorDIYHelp_1'|translate }}</li>
<li>{{ 'CoreUpdater_ErrorDIYHelp_2'|translate }}</li>
<li>{{ 'CoreUpdater_ErrorDIYHelp_3'|translate }} <a href='https://piwik.org/faq/how-to-update/#faq_179' target='_blank'>(see FAQ)</a></li>
<li>{{ 'CoreUpdater_ErrorDIYHelp_4'|translate }}</li>
<li>{{ 'CoreUpdater_ErrorDIYHelp_5'|translate }}</li>
</ul>
</p>
{% else %}
{% if warningMessages|length > 0 %}
<div class="warning">
<img src="plugins/Zeitgeist/images/warning_medium.png"/> {{ 'CoreUpdater_WarningMessages'|translate }}
<ul>
{% for message in warningMessages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
{% if errorMessages|length > 0 %}
<div class="error">
<img src="plugins/Zeitgeist/images/error_medium.png"/> {{ 'CoreUpdater_ErrorDuringPluginsUpdates'|translate }}
<ul>
{% for message in errorMessages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% if deactivatedPlugins is defined and deactivatedPlugins|length > 0 %}
{% set listOfDeactivatedPlugins=deactivatedPlugins|join(', ') %}
<p style="color:red;">
<img src="plugins/Zeitgeist/images/error_medium.png"/>
{{ 'CoreUpdater_WeAutomaticallyDeactivatedTheFollowingPlugins'|translate(listOfDeactivatedPlugins) }}
</p>
{% endif %}
</div>
{% endif %}
{% if errorMessages|length > 0 or warningMessages|length > 0 %}
<p>{{ 'CoreUpdater_HelpMessageIntroductionWhenWarning'|translate }}
<ul>
<li>{{ helpMessage }}</li>
</ul>
</p>
{% else %}
<div class="success"> {{ 'Installation_TablesUpdatedSuccess'|translate(oldVersion, currentVersion) }}
<img src="plugins/Zeitgeist/images/success_medium.png"/></div>
<br />
{% endif %}
{% endif %}
</div>
{% endblock %}

View file

@ -0,0 +1,21 @@
{% extends '@Installation/layout.twig' %}
{% block content %}
{% if not showNextStep %}
{% include "@Installation/_systemCheckLegend.twig" %}
<br style="clear:both;">
{% endif %}
<h3>{{ 'Installation_SystemCheck'|translate }}</h3>
<br/>
{% include "@Installation/_systemCheckSection.twig" %}
{% if not showNextStep %}
<br/>
<p>
<img src='plugins/Zeitgeist/images/link.gif'/> &nbsp;
<a href="?module=Proxy&action=redirect&url=http://piwik.org/docs/requirements/" target="_blank">{{ 'Installation_Requirements'|translate }}</a>
</p>
{% include "@Installation/_systemCheckLegend.twig" %}
{% endif %}
{% endblock %}

View file

@ -0,0 +1,20 @@
{% extends 'admin.twig' %}
{% block content %}
{% if isSuperUser %}
<h2 piwik-enriched-headline>{{ 'Installation_SystemCheck'|translate }}</h2>
<p style="margin-left:1em;">
{% if infos.has_errors %}
<img src="plugins/Zeitgeist/images/error.png"/>
{{ 'Installation_SystemCheckSummaryThereWereErrors'|translate('<strong>','</strong>','<strong><em>','</em></strong>')|raw }} {{ 'Installation_SeeBelowForMoreInfo'|translate }}
{% elseif infos.has_warnings %}
<img src="plugins/Zeitgeist/images/warning.png"/>
{{ 'Installation_SystemCheckSummaryThereWereWarnings'|translate }} {{ 'Installation_SeeBelowForMoreInfo'|translate }}
{% else %}
<img src="plugins/Zeitgeist/images/ok.png"/>
{{ 'Installation_SystemCheckSummaryNoProblems'|translate }}
{% endif %}
</p>
{% include "@Installation/_systemCheckSection.twig" %}
{% endif %}
{% endblock %}

View file

@ -0,0 +1,61 @@
{% extends '@Installation/layout.twig' %}
{% block content %}
<h2>{{ 'Installation_Tables'|translate }}</h2>
{% if someTablesInstalled is defined %}
<div class="warning">{{ 'Installation_TablesWithSameNamesFound'|translate("<span id='linkToggle'>","</span>")|raw }}
<img src="plugins/Zeitgeist/images/warning_medium.png"/>
</div>
<div id="toggle" style="display:none;color:#4F2410;font-size: small;">
<em>{{ 'Installation_TablesFound'|translate }}: <br/>
{{ tablesInstalled }} </em>
</div>
{% if showReuseExistingTables is defined %}
<p>{{ 'Installation_TablesWarningHelp'|translate }}</p>
<p class="nextStep"><a href="{{ linkTo({'action':'reuseTables'}) }}">{{ 'Installation_TablesReuse'|translate }} &raquo;</a></p>
{% else %}
<p class="nextStep"><a href="{{ linkTo({'action':previousPreviousModuleName}) }}">&laquo; {{ 'Installation_GoBackAndDefinePrefix'|translate }}</a></p>
{% endif %}
<p class="nextStep"><a href="{{ linkTo({'deleteTables':1}) }}" id="eraseAllTables">{{ 'Installation_TablesDelete'|translate }} &raquo;</a></p>
{% endif %}
{% if existingTablesDeleted is defined %}
<div class="success"> {{ 'Installation_TablesDeletedSuccess'|translate }}
<img src="plugins/Zeitgeist/images/success_medium.png"/></div>
{% endif %}
{% if tablesCreated is defined %}
<div class="success"> {{ 'Installation_TablesCreatedSuccess'|translate }}
<img src="plugins/Zeitgeist/images/success_medium.png"/></div>
{% endif %}
<script>
$(document).ready(function () {
var strConfirmEraseTables = "{{ 'Installation_ConfirmDeleteExistingTables'|translate("["~tablesInstalled~"]") }} ";
// toggle the display of the tables detected during the installation when clicking
// on the span "linkToggle"
$("#linkToggle")
.css("border-bottom", "thin dotted #ff5502")
.hover(function () {
$(this).css({ cursor: "pointer"});
},
function () {
$(this).css({ cursor: "auto"});
})
.css("border-bottom", "thin dotted #ff5502")
.click(function () {
$("#toggle").toggle();
});
$("#eraseAllTables").click(function () {
if (!confirm(strConfirmEraseTables)) {
return false;
}
});
});
</script>
{% endblock %}

View file

@ -0,0 +1,17 @@
{% extends '@Installation/layout.twig' %}
{% block content %}
{% if displayfirstWebsiteSetupSuccess is defined %}
<span id="toFade" class="success">
{{ 'Installation_SetupWebsiteSetupSuccess'|translate(displaySiteName) }}
<img src="plugins/Zeitgeist/images/success_medium.png"/>
</span>
{% endif %}
{{ trackingHelp|raw }}
<br/><br/>
<h2>{{ 'Installation_LargePiwikInstances'|translate }}</h2>
{{ 'Installation_JsTagArchivingHelp1'|translate('<a target="_blank" href="http://piwik.org/docs/setup-auto-archiving/">','</a>')|raw }}
{{ 'General_ReadThisToLearnMore'|translate('<a target="_blank" href="http://piwik.org/docs/optimize/">','</a>')|raw }}
{% endblock %}

View file

@ -0,0 +1,45 @@
{% extends '@Installation/layout.twig' %}
{% block content %}
<h2>{{ 'Installation_Welcome'|translate }}</h2>
{% if newInstall %}
{{ 'Installation_WelcomeHelp'|translate(totalNumberOfSteps)|raw }}
{% else %}
<p>{{ 'Installation_ConfigurationHelp'|translate }}</p>
<br/>
<div class="error">
{{ errorMessage }}
</div>
{% endif %}
<script type="text/javascript">
<!--
$(function () {
// client-side test for https to handle the case where the server is behind a reverse proxy
if (document.location.protocol === 'https:') {
$('p.nextStep a').attr('href', $('p.nextStep a').attr('href') + '&clientProtocol=https');
}
// client-side test for broken tracker (e.g., mod_security rule)
$('p.nextStep').hide();
$.ajax({
url: 'piwik.php',
data: 'url=http://example.com',
complete: function () {
$('p.nextStep').show();
},
error: function (req) {
$('p.nextStep a').attr('href', $('p.nextStep a').attr('href') + '&trackerStatus=' + req.status);
}
});
});
//-->
</script>
{% if not showNextStep %}
<p class="nextStep">
<a href="{{url}}">{{ 'General_RefreshPage'|translate }} &raquo;</a>
</p>
{% endif %}
{% endblock %}