Merge branch 'master' into template

This commit is contained in:
Etienne Roudeix
2013-09-17 16:53:57 +02:00
44 changed files with 10697 additions and 635 deletions

View File

@@ -40,6 +40,8 @@
</loops>
<forms>
<form name="thelia.install.step3" class="Thelia\Form\InstallStep3Form"/>
<form name="thelia.customer.creation" class="Thelia\Form\CustomerCreation"/>
<form name="thelia.customer.modification" class="Thelia\Form\CustomerModification"/>
<form name="thelia.customer.lostpassword" class="Thelia\Form\CustomerLostPasswordForm"/>
@@ -53,6 +55,9 @@
<form name="thelia.admin.category.creation" class="Thelia\Form\CategoryCreationForm"/>
<form name="thelia.admin.category.modification" class="Thelia\Form\CategoryModificationForm"/>
<form name="thelia.admin.product.creation" class="Thelia\Form\ProductCreationForm"/>
<form name="thelia.admin.product.modification" class="Thelia\Form\ProductModificationForm"/>
<form name="thelia.admin.product.creation" class="Thelia\Form\ProductCreationForm"/>
<form name="thelia.admin.product.deletion" class="Thelia\Form\ProductModificationForm"/>

View File

@@ -56,17 +56,6 @@
<tag name="router.register" priority="0"/>
</service>
<service id="router.install" class="%router.class%">
<argument type="service" id="router.xmlLoader"/>
<argument>install.xml</argument>
<argument type="collection">
<argument key="cache_dir">%kernel.cache_dir%</argument>
<argument key="debug">%kernel.debug%</argument>
</argument>
<argument type="service" id="request.context"/>
<tag name="router.register" priority="-1"/>
</service>
<service id="router.front" class="%router.class%">
<argument type="service" id="router.xmlLoader"/>
<argument>front.xml</argument>

View File

@@ -1,31 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
<route id="install.step1" path="/install" >
<default key="_controller">Thelia\Controller\Install\InstallController::index</default>
</route>
<route id="install.step2" path="/install/step/2" >
<default key="_controller">Thelia\Controller\Install\InstallController::checkPermission</default>
</route>
<route id="install.step3" path="/install/step/3" >
<default key="_controller">Thelia\Controller\Install\InstallController::databaseConnection</default>
</route>
<route id="install.step4" path="/install/step/4" >
<default key="_controller">Thelia\Controller\Install\InstallController::databaseSelection</default>
</route>
<route id="install.step5" path="/install/step/5" >
<default key="_controller">Thelia\Controller\Install\InstallController::generalInformation</default>
</route>
<route id="install.step6" path="/install/thanks" >
<default key="_controller">Thelia\Controller\Install\InstallController::thanks</default>
</route>
</routes>

View File

@@ -31,6 +31,7 @@ use Symfony\Component\Routing\Exception\MissingMandatoryParametersException;
use Symfony\Component\Routing\Exception\RouteNotFoundException;
use Symfony\Component\Routing\Router;
use Thelia\Core\Security\SecurityContext;
use Thelia\Core\Translation\Translator;
use Thelia\Tools\URL;
use Thelia\Tools\Redirect;
use Thelia\Core\Template\ParserContext;
@@ -97,7 +98,7 @@ class BaseController extends ContainerAware
*
* return the Translator
*
* @return mixed \Thelia\Core\Translation\Translator
* @return Translator
*/
public function getTranslator()
{

View File

@@ -1,59 +0,0 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Controller\Install;
use Symfony\Component\HttpFoundation\Response;
use Thelia\Controller\BaseController;
/**
* Class BaseInstallController
* @package Thelia\Controller\Install
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class BaseInstallController extends BaseController
{
/**
* @return a ParserInterface instance parser
*/
protected function getParser()
{
$parser = $this->container->get("thelia.parser");
// Define the template that shoud be used
$parser->setTemplate("install");
return $parser;
}
public function render($templateName, $args = array())
{
return new Response($this->renderRaw($templateName, $args));
}
public function renderRaw($templateName, $args = array())
{
$data = $this->getParser()->render($templateName, $args);
return $data;
}
}

View File

@@ -1,111 +0,0 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Controller\Install;
use Thelia\Install\CheckPermission;
/**
* Class InstallController
* @package Thelia\Controller\Install
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
class InstallController extends BaseInstallController
{
public function index()
{
//$this->verifyStep(1);
$this->getSession()->set("step", 1);
return $this->render("index.html");
}
public function checkPermission()
{
//$this->verifyStep(2);
//$permission = new CheckPermission();
$this->getSession()->set("step", 2);
return $this->render("step-2.html");
}
public function databaseConnection()
{
//$this->verifyStep(2);
//$permission = new CheckPermission();
$this->getSession()->set("step", 3);
return $this->render("step-3.html");
}
public function databaseSelection()
{
//$this->verifyStep(2);
//$permission = new CheckPermission();
$this->getSession()->set("step", 4);
return $this->render("step-4.html");
}
public function generalInformation()
{
//$this->verifyStep(2);
//$permission = new CheckPermission();
$this->getSession()->set("step", 5);
return $this->render("step-5.html");
}
public function thanks()
{
//$this->verifyStep(2);
//$permission = new CheckPermission();
$this->getSession()->set("step", 6);
return $this->render("thanks.html");
}
protected function verifyStep($step)
{
$session = $this->getSession();
if ($session->has("step")) {
$sessionStep = $session->get("step");
} else {
return true;
}
switch ($step) {
case "1" :
if ($sessionStep > 1) {
$this->redirect("/install/step/2");
}
break;
}
}
}

View File

@@ -86,6 +86,8 @@ class Thelia extends Kernel
$serviceContainer->setLogger('defaultLogger', \Thelia\Log\Tlog::getInstance());
$con->useDebug(true);
}
}
/**

View File

@@ -0,0 +1,111 @@
<?php
/**********************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/**********************************************************************************/
namespace Thelia\Form;
use Symfony\Component\Validator\Constraints\GreaterThan;
use Symfony\Component\Validator\Constraints\NotBlank;
/**
* Created by JetBrains PhpStorm.
* Date: 8/29/13
* Time: 3:45 PM
*
* Allow to build a form Install Step 3 Database connection
*
* @package Coupon
* @author Guillaume MOREL <gmorel@openstudio.fr>
*
*/
class InstallStep3Form extends BaseForm
{
/**
* Build Coupon form
*
* @return void
*/
protected function buildForm()
{
$this->formBuilder
->add(
'host',
'text',
array(
'constraints' => array(
new NotBlank()
)
)
)
->add(
'user',
'text',
array(
'constraints' => array(
new NotBlank()
)
)
)
->add(
'password',
'text',
array(
'constraints' => array(
new NotBlank()
)
)
)
->add(
'port',
'text',
array(
'constraints' => array(
new NotBlank(),
new GreaterThan(
array(
'value' => 0
)
)
)
)
)
->add(
'locale',
'hidden',
array(
'constraints' => array(
new NotBlank()
)
)
);
}
/**
* Get form name
*
* @return string
*/
public function getName()
{
return 'thelia_install_step3';
}
}

View File

@@ -25,19 +25,33 @@ use Thelia\Install\Exception\AlreadyInstallException;
/**
* Class BaseInstall
*
* @author Manuel Raynaud <mraynaud@openstudio.fr>
*/
abstract class BaseInstall
{
/** @var bool If Installation wizard is launched by CLI */
protected $isConsoleMode = true;
/**
* Verify if an installation already exists
* Constructor
*
* @param bool $verifyInstall Verify if an installation already exists
*
* @throws Exception\AlreadyInstallException
*/
public function __construct($verifyInstall = true)
{
/* TODO : activate this part
// Check if install wizard is launched via CLI
if (php_sapi_name() == 'cli') {
$this->isConsoleMode = true;
} else {
$this->isConsoleMode = false;
}
if (file_exists(THELIA_ROOT . '/local/config/database.yml') && $verifyInstall) {
throw new AlreadyInstallException("Thelia is already installed");
}*/
}
$this->exec();

View File

@@ -0,0 +1,122 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Install;
use PDO;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use Symfony\Component\Translation\TranslatorInterface;
use Thelia\Core\Translation\Translator;
use Thelia\Install\Exception\InstallException;
/**
* Class CheckDatabaseConnection
*
* Take care of integration tests (database connection)
*
* @package Thelia\Install
* @author Manuel Raynaud <mraynaud@openstudio.fr>
* @author Guillaume MOREL <gmorel@openstudio.fr>
*/
class CheckDatabaseConnection extends BaseInstall
{
protected $validationMessages = array();
/** @var bool If permissions are OK */
protected $isValid = true;
/** @var TranslatorInterface Translator Service */
protected $translator = null;
/** @var string Database host information */
protected $host = null;
/** @var string Database user information */
protected $user = null;
/** @var string Database password information */
protected $password = null;
/** @var int Database port information */
protected $port = null;
/**
* @var \PDO instance
*/
protected $connection = null;
/**
* Constructor
*
* @param string $host Database host information
* @param string $user Database user information
* @param string $password Database password information
* @param int $port Database port information
* @param bool $verifyInstall If verify install
* @param Translator $translator Translator Service
* necessary for install wizard
*/
public function __construct($host, $user, $password, $port, $verifyInstall = true, Translator $translator = null)
{
$this->host = $host;
$this->user = $user;
$this->password = $password;
$this->port = $port;
parent::__construct($verifyInstall);
}
/**
* Perform database connection check
*
* @return bool
*/
public function exec()
{
$dsn = "mysql:host=%s;port=%s";
try {
$this->connection = new \PDO(
sprintf($dsn, $this->host, $this->port),
$this->user,
$this->password
);
} catch (\PDOException $e) {
$this->validationMessages = 'Wrong connection information';
$this->isValid = false;
}
return $this->isValid;
}
public function getConnection()
{
return $this->connection;
}
}

View File

@@ -23,56 +23,364 @@
namespace Thelia\Install;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use Symfony\Component\Translation\TranslatorInterface;
use Thelia\Core\Translation\Translator;
/**
* Class CheckPermission
*
* Take care of integration tests (files permissions)
*
* @package Thelia\Install
* @author Manuel Raynaud <mraynaud@openstudio.fr>
* @author Manuel Raynaud <mraynaud@openstudio.fr>
* @author Guillaume MOREL <gmorel@openstudio.fr>
*/
class CheckPermission extends BaseInstall
{
const CONF = "const";
const LOG = "log";
const CACHE = "cache";
private $directories = array();
private $validation = array();
private $valid = true;
const DIR_CONF = 'local/config';
const DIR_LOG = 'log';
const DIR_CACHE = 'cache';
public function __construct($verifyInstall = true)
/** @var array Directory needed to be writable */
protected $directoriesToBeWritable = array(
self::DIR_CONF,
self::DIR_LOG,
self::DIR_CACHE,
);
/** @var array Minimum server configuration necessary */
protected $minServerConfigurationNecessary = array(
'memory_limit' => 134217728,
'post_max_size' => 20971520,
'upload_max_filesize' => 2097152
);
protected $validationMessages = array();
/** @var bool If permissions are OK */
protected $isValid = true;
/** @var TranslatorInterface Translator Service */
protected $translator = null;
/**
* Constructor
*
* @param bool $verifyInstall If verify install
* @param Translator $translator Translator Service
* necessary for install wizard
*/
public function __construct($verifyInstall = true, Translator $translator = null)
{
$this->translator = $translator;
$this->directories = array(
self::CONF => THELIA_ROOT . "local/config",
self::LOG => THELIA_ROOT . "log",
self::CACHE => THELIA_ROOT . "cache"
$this->validationMessages['php_version'] = array(
'text' => $this->getI18nPhpVersionText('5.4', phpversion(), true),
'hint' => $this->getI18nPhpVersionHint(),
'status' => true
);
$this->validation = array(
self::CONF => array(
"text" => sprintf("config directory(%s)...", $this->directories[self::CONF]),
"status" => true
),
self::LOG => array(
"text" => sprintf("cache directory(%s)...", $this->directories[self::LOG]),
"status" => true
),
self::CACHE => array(
"text" => sprintf("log directory(%s)...", $this->directories[self::CACHE]),
"status" => true
)
);
foreach ($this->directoriesToBeWritable as $directory) {
$this->validationMessages[$directory] = array(
'text' => '',
'hint' => '',
'status' => true
);
}
foreach ($this->minServerConfigurationNecessary as $key => $value) {
$this->validationMessages[$key] = array(
'text' => '',
'hint' => $this->getI18nConfigHint(),
'status' => true
);
}
parent::__construct($verifyInstall);
}
/**
* Perform file permission check
*
* @return bool
*/
public function exec()
{
foreach ($this->directories as $key => $directory) {
if(is_writable($directory) === false) {
$this->valid = false;
$this->validation[$key]["status"] = false;
if (version_compare(phpversion(), '5.4', '<')) {
$this->validationMessages['php_version'] = $this->getI18nPhpVersionText('5.4', phpversion(), false);
}
foreach ($this->directoriesToBeWritable as $directory) {
$fullDirectory = THELIA_ROOT . $directory;
$this->validationMessages[$directory]['text'] = $this->getI18nDirectoryText($fullDirectory, true);
if (is_writable($fullDirectory) === false) {
if (!$this->makeDirectoryWritable($fullDirectory)) {
$this->isValid = false;
$this->validationMessages[$directory]['status'] = false;
$this->validationMessages[$directory]['text'] = $this->getI18nDirectoryText($fullDirectory, false);
$this->validationMessages[$directory]['hint'] = $this->getI18nDirectoryHint($fullDirectory);
}
}
}
foreach ($this->minServerConfigurationNecessary as $key => $value) {
$this->validationMessages[$key]['text'] = $this->getI18nConfigText($key, $this->formatBytes($value), ini_get($key), true);
if (!$this->verifyServerMemoryValues($key, $value)) {
$this->isValid = false;
$this->validationMessages[$key]['status'] = false;
$this->validationMessages[$key]['text'] = $this->getI18nConfigText($key, $this->formatBytes($value), ini_get($key), false);;
}
}
return $this->isValid;
}
}
/**
* Get validation messages
*
* @return array
*/
public function getValidationMessages()
{
return $this->validationMessages;
}
/**
* Make a directory writable (recursively)
*
* @param string $directory path to directory
*
* @return bool
*/
protected function makeDirectoryWritable($directory)
{
chmod($directory, 0777);
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($directory)
);
foreach ($iterator as $item) {
chmod($item, 0777);
}
return (is_writable(THELIA_ROOT . $directory) === true);
}
/**
* Get Translated text about the directory state
*
* @param string $directory Directory being checked
* @param bool $isValid If directory permission is valid
*
* @return string
*/
protected function getI18nDirectoryText($directory, $isValid)
{
if ($this->translator !== null) {
if ($isValid) {
$sentence = 'Your directory <strong>%directory%</strong> is writable';
} else {
$sentence = 'Your directory <strong>%directory%</strong> is not writable';
}
$translatedText = $this->translator->trans(
$sentence,
array(
'%directory%' => $directory
),
'install-wizard'
);
} else {
$translatedText = sprintf('Your directory %s needs to be writable', $directory);
}
return $translatedText;
}
/**
* Get Translated hint about the directory state
*
* @param string $directory Directory being checked
*
* @return string
*/
protected function getI18nDirectoryHint($directory)
{
if ($this->translator !== null) {
$sentence = '<span class="label label-primary">chmod 777 %directory%</span> on your server with admin rights could help';
$translatedText = $this->translator->trans(
$sentence,
array(
'%directory%' => $directory
),
'install-wizard'
);
} else {
$translatedText = sprintf('chmod 777 %s on your server with admin rights could help', $directory);
}
return $translatedText;
}
/**
* Get Translated text about the directory state
* Not usable with CLI
*
* @param string $key .ini file key
* @param string $expectedValue Expected server value
* @param string $currentValue Actual server value
* @param bool $isValid If server configuration is valid
*
* @return string
*/
protected function getI18nConfigText($key, $expectedValue, $currentValue, $isValid)
{
if ($isValid) {
$sentence = 'Your <span class="label label-primary">%key%</span> server configuration (currently %currentValue%) is well enough to run Thelia2 (%expectedValue% needed)';
} else {
$sentence = 'Your <span class="label label-primary">%key%</span> server configuration (currently %currentValue%) is not sufficient enough in order to run Thelia2 (%expectedValue% needed)';
}
$translatedText = $this->translator->trans(
$sentence,
array(
'%key%' => $key,
'%expectedValue%' => $expectedValue,
'%currentValue%' => $currentValue,
),
'install-wizard'
);
return $translatedText;
}
/**
* Get Translated hint about the config requirement issue
*
* @return string
*/
protected function getI18nConfigHint()
{
$sentence = 'Modifying this value on your server <span class="label label-primary">php.ini</span> file with admin rights could help';
$translatedText = $this->translator->trans(
$sentence,
array(),
'install-wizard'
);
return $translatedText;
}
/**
* Get Translated hint about the PHP version requirement issue
*
* @param string $expectedValue
* @param string $currentValue
* @param bool $isValid
*
* @return string
*/
protected function getI18nPhpVersionText($expectedValue, $currentValue, $isValid)
{
if ($this->translator !== null) {
if ($isValid) {
$sentence = 'Your PHP version <span class="label label-primary">%currentValue%</span> is well enough to run Thelia2 (%expectedValue% needed)';
} else {
$sentence = 'Your PHP version <span class="label label-primary">%currentValue%</span> is not sufficient enough to run Thelia2 (%expectedValue% needed)';
}
$translatedText = $this->translator->trans(
$sentence,
array(
'%expectedValue%' => $expectedValue,
'%currentValue%' => $currentValue,
),
'install-wizard'
);
} else {
$translatedText = sprintf('Thelia needs at least PHP %s (%s currently)', $expectedValue, $currentValue);
}
return $translatedText;
}
/**
* Get Translated hint about the config requirement issue
*
* @return string
*/
protected function getI18nPhpVersionHint()
{
$sentence = 'Upgrading your version of PHP with admin rights could help';
$translatedText = $this->translator->trans(
$sentence,
array(),
'install-wizard'
);
return $translatedText;
}
/**
* Check if a server memory value is met or not
*
* @param string $key .ini file key
* @param int $necessaryValueInBytes Expected value in bytes
*
* @return bool
*/
protected function verifyServerMemoryValues($key, $necessaryValueInBytes)
{
$serverValueInBytes = $this->returnBytes(ini_get($key));
return ($serverValueInBytes >= $necessaryValueInBytes);
}
/**
* Return bytes from memory .ini value
*
* @param string $val .ini value
*
* @return int
*/
protected function returnBytes($val)
{
$val = trim($val);
$last = strtolower($val[strlen($val)-1]);
switch($last) {
// The 'G' modifier is available since PHP 5.1.0
case 'g':
$val *= 1024;
case 'm':
$val *= 1024;
case 'k':
$val *= 1024;
}
return $val;
}
/**
* Convert bytes to readable string
*
* @param int $bytes bytes
* @param int $precision conversion precision
*
* @return string
*/
protected function formatBytes($bytes, $precision = 2)
{
$base = log($bytes) / log(1024);
$suffixes = array('', 'k', 'M', 'G', 'T');
return round(pow(1024, $base - floor($base)), $precision) . $suffixes[floor($base)];
}
}

View File

@@ -93,7 +93,7 @@ class Database
*/
public function createDatabase($dbName)
{
$this->connection->query(
$this->connection->exec(
sprintf(
"CREATE DATABASE IF NOT EXISTS %s CHARACTER SET utf8",
$dbName

View File

@@ -34,8 +34,6 @@ class Admin extends BaseAdmin implements UserInterface
public function setPassword($password)
{
\Thelia\Log\Tlog::getInstance()->debug($password);
if ($this->isNew() && ($password === null || trim($password) == "")) {
throw new \InvalidArgumentException("customer password is mandatory on creation");
}