Merge branch 'master' of github.com:thelia/thelia
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -17,3 +17,4 @@ coverage
|
||||
local/cache/*
|
||||
composer.lock
|
||||
web/assets/*
|
||||
web/.htaccess
|
||||
|
||||
@@ -27,8 +27,6 @@
|
||||
|
||||
"symfony/form": "2.2.*",
|
||||
"symfony/validator": "2.2.*",
|
||||
"symfony/security": "2.2.*",
|
||||
"symfony/templating": "2.2.*",
|
||||
|
||||
"smarty/smarty": "v3.1.13",
|
||||
"kriswallsmith/assetic": "1.2.*@dev",
|
||||
|
||||
@@ -28,17 +28,23 @@ use Thelia\Form\AdminLogin;
|
||||
|
||||
class AdminController extends BaseAdminController {
|
||||
|
||||
public function indexAction()
|
||||
public function loginAction()
|
||||
{
|
||||
|
||||
$form = $this->getLoginForm();
|
||||
|
||||
$request = $this->getRequest();
|
||||
|
||||
if($request->isMethod("POST")) {
|
||||
|
||||
$form->bind($request);
|
||||
|
||||
if ($form->isValid()) {
|
||||
|
||||
$this->container->get('request')->authenticate(
|
||||
$form->get('username')->getData(),
|
||||
$form->get('password')->getData()
|
||||
);
|
||||
|
||||
echo "valid"; exit;
|
||||
}
|
||||
}
|
||||
@@ -48,6 +54,15 @@ class AdminController extends BaseAdminController {
|
||||
));
|
||||
}
|
||||
|
||||
public function indexAction()
|
||||
{
|
||||
$form = $this->getLoginForm();
|
||||
|
||||
return $this->render("login.html", array(
|
||||
"form" => $form->createView()
|
||||
));
|
||||
}
|
||||
|
||||
protected function getLoginForm()
|
||||
{
|
||||
$adminLogin = new AdminLogin($this->getRequest());
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
<loops>
|
||||
<loop class="Thelia\Core\Template\Loop\Category" name="category"/>
|
||||
<loop class="Thelia\Core\Template\Loop\Product" name="product"/>
|
||||
</loops>
|
||||
|
||||
|
||||
@@ -68,6 +69,10 @@
|
||||
<tag name="thelia.parser.register_plugin"/>
|
||||
</service>
|
||||
|
||||
<service id="smarty.plugin.theliasyntax" class="Thelia\Core\Template\Smarty\Plugins\TheliaSyntax" >
|
||||
<tag name="thelia.parser.register_plugin"/>
|
||||
</service>
|
||||
|
||||
<service id="smarty.plugin.thelialoop" class="Thelia\Core\Template\Smarty\Plugins\TheliaLoop" scope="request">
|
||||
<tag name="thelia.parser.register_plugin"/>
|
||||
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
<?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\Core\Security\Authentication;
|
||||
|
||||
use Thelia\Core\Security\UserNotFoundException;
|
||||
use Thelia\Core\Security\IncorrectPasswordException;
|
||||
|
||||
/**
|
||||
* Aunthentication providers are in charge or retrieving users, and check their
|
||||
* credentials.
|
||||
*
|
||||
* @author Franck
|
||||
*
|
||||
*/
|
||||
interface AuthenticationProviderInterface {
|
||||
|
||||
/**
|
||||
* Set the authentication token
|
||||
*
|
||||
* @param TokenInterface $token the authentication token
|
||||
*/
|
||||
public function setToken(TokenInterface $token);
|
||||
|
||||
|
||||
/**
|
||||
* Set the authentication token
|
||||
*
|
||||
* @param unknown $key
|
||||
*/
|
||||
public function supportsToken(TokenInterface $token);
|
||||
|
||||
/**
|
||||
* Authenticate the token
|
||||
*
|
||||
*@throws Exception if authentication was not successful
|
||||
*/
|
||||
public function authenticate();
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,67 @@
|
||||
<?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\Core\Security\Authentication;
|
||||
|
||||
use Thelia\Core\Security\Authentication\AuthenticationProviderInterface;
|
||||
use Thelia\Core\Security\Encoder\PasswordEncoderInterface;
|
||||
use Thelia\Core\Security\User\UserProviderInterface;
|
||||
use Thelia\Security\Token\TokenInterface;
|
||||
use Thelia\Core\Security\Exception\IncorrectPasswordException;
|
||||
use Thelia\Core\Security\Token\UsernamePasswordToken;
|
||||
|
||||
class UsernamePasswordAuthenticator implements AuthenticationProviderInterface {
|
||||
|
||||
protected $userProvider;
|
||||
protected $encoder;
|
||||
|
||||
private $token;
|
||||
|
||||
public function __construct(UserProviderInterface $userProvider, PasswordEncoderInterface $encoder) {
|
||||
$this->userProvider = $userProvider;
|
||||
$this->encoder = $encoder;
|
||||
}
|
||||
|
||||
public function supportsToken(TokenInterface $token) {
|
||||
|
||||
return $token instanceof UsernamePasswordToken;
|
||||
}
|
||||
|
||||
public function authenticate($token) {
|
||||
|
||||
if (!$this->supports($token)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Retreive user
|
||||
$user = $this->userProvider->getUser($this->token->getUsername());
|
||||
|
||||
// Check password
|
||||
$authOk = $this->encoder->isEqual($password, $user->getPassword(), $user->getAlgo(), $user->getSalt()) === true;
|
||||
|
||||
$authenticatedToken = new UsernamePasswordToken($user, $token->getCredentials(), $authOk);
|
||||
|
||||
return $authenticatedToken;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?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\Core\Security\Encoder;
|
||||
|
||||
/**
|
||||
* This interface defines a password encoder.
|
||||
*
|
||||
* @author Franck Allimant <franck@cqfdev.fr>
|
||||
*
|
||||
*/
|
||||
interface PasswordEncoderInterface {
|
||||
|
||||
/**
|
||||
* Encode a string.
|
||||
*
|
||||
* @param string $password the password to encode
|
||||
* @param string $algorithm the hash() algorithm
|
||||
* @return string $salt the salt
|
||||
*/
|
||||
public function encode($password, $algorithm, $salt);
|
||||
|
||||
/**
|
||||
* Check a string against an encoded password.
|
||||
*
|
||||
* @param string $string the string to compare against password
|
||||
* @param string $password the encoded password
|
||||
* @param string $algorithm the hash() algorithm
|
||||
* @return string $salt the salt
|
||||
*/
|
||||
public function isEqual($string, $password, $algorithm, $salt);
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?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\Core\Security\Encoder;
|
||||
|
||||
/**
|
||||
* This interface defines a hash based password encoder.
|
||||
*
|
||||
* @author Franck Allimant <franck@cqfdev.fr>
|
||||
*/
|
||||
|
||||
class PasswordHashEncoder implements PasswordEncoderInterface {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function encode($password, $algorithm, $salt)
|
||||
{
|
||||
if (!in_array($algorithm, hash_algos(), true)) {
|
||||
throw new \LogicException(sprintf('The algorithm "%s" is not supported.', $algorithm));
|
||||
}
|
||||
|
||||
// Salt the string
|
||||
$salted = $password.$salt;
|
||||
|
||||
// Create the hash
|
||||
$digest = hash($algorithm, $salted, true);
|
||||
|
||||
// "stretch" hash
|
||||
for ($i = 1; $i < 5000; $i++) {
|
||||
$digest = hash($algorithm, $digest.$salted, true);
|
||||
}
|
||||
|
||||
return base64_encode($digest);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isEqual($string, $password, $algorithm, $salt)
|
||||
{
|
||||
$encoded = $this->encode($password, $algorithm, $salt);
|
||||
|
||||
return $encoded == $string;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?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\Core\Security\Exception;
|
||||
|
||||
class AuthenticationTokenNotFoundException extends \Exception
|
||||
{
|
||||
}
|
||||
81
core/lib/Thelia/Core/Security/SecurityManager.php
Normal file
81
core/lib/Thelia/Core/Security/SecurityManager.php
Normal file
@@ -0,0 +1,81 @@
|
||||
<?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\Core\Security;
|
||||
|
||||
use Thelia\Core\Security\Authentication\AuthenticationProviderInterface;
|
||||
use Thelia\Core\Security\Exception\AuthenticationTokenNotFoundException;
|
||||
|
||||
/**
|
||||
* A simple security manager, in charge of authenticating users using various authentication systems.
|
||||
*
|
||||
* @author Franck Allimant <franck@cqfdev.fr>
|
||||
*/
|
||||
class SecurityManager {
|
||||
|
||||
protected $authProvider;
|
||||
|
||||
public function __construct(AuthenticationProviderInterface $authProvider) {
|
||||
$this->authProvider = $authProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the current token is authenticated
|
||||
*
|
||||
* @throws AuthenticationCredentialsNotFoundException when the security context has no authentication token.
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
final public function isGranted()
|
||||
{
|
||||
if (null === $this->token) {
|
||||
throw new AuthenticationTokenNotFoundException('The security context contains no authentication token.');
|
||||
}
|
||||
|
||||
if (!$this->token->isAuthenticated()) {
|
||||
$this->token = $this->authProvider->authenticate($this->token);
|
||||
}
|
||||
|
||||
return $this->token->isAuthenticated();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the currently authenticated token.
|
||||
*
|
||||
* @return TokenInterface|null A TokenInterface instance or null if no authentication information is available
|
||||
*/
|
||||
public function getToken()
|
||||
{
|
||||
return $this->token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the token.
|
||||
*
|
||||
* @param TokenInterface $token A TokenInterface token, or null if no further authentication information should be stored
|
||||
*/
|
||||
public function setToken(TokenInterface $token = null)
|
||||
{
|
||||
$this->token = $token;
|
||||
}
|
||||
}
|
||||
148
core/lib/Thelia/Core/Security/Token/AbstractToken.php
Normal file
148
core/lib/Thelia/Core/Security/Token/AbstractToken.php
Normal file
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
namespace Thelia\Core\Security\Token;
|
||||
|
||||
use Thelia\Core\Security\User\UserInterface;
|
||||
|
||||
/**
|
||||
* Base class for Token instances.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
abstract class AbstractToken implements TokenInterface
|
||||
{
|
||||
private $user;
|
||||
private $authenticated;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param RoleInterface[] $roles An array of roles
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authenticated = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getUsername()
|
||||
{
|
||||
if ($this->user instanceof UserInterface) {
|
||||
return $this->user->getUsername();
|
||||
}
|
||||
|
||||
return (string) $this->user;
|
||||
}
|
||||
|
||||
public function getUser()
|
||||
{
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the user in the token.
|
||||
*
|
||||
* The user can be a UserInterface instance, or an object implementing
|
||||
* a __toString method or the username as a regular string.
|
||||
*
|
||||
* @param mixed $user The user
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function setUser($user)
|
||||
{
|
||||
if (!($user instanceof UserInterface || is_string($user))) {
|
||||
throw new \InvalidArgumentException('$user must be an instanceof UserInterface, or a primitive string.');
|
||||
}
|
||||
|
||||
if (null === $this->user) {
|
||||
$changed = false;
|
||||
} elseif ($this->user instanceof UserInterface) {
|
||||
if (!$user instanceof UserInterface) {
|
||||
$changed = true;
|
||||
} else {
|
||||
$changed = $this->hasUserChanged($user);
|
||||
}
|
||||
} elseif ($user instanceof UserInterface) {
|
||||
$changed = true;
|
||||
} else {
|
||||
$changed = (string) $this->user !== (string) $user;
|
||||
}
|
||||
|
||||
if ($changed) {
|
||||
$this->setAuthenticated(false);
|
||||
}
|
||||
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isAuthenticated()
|
||||
{
|
||||
return $this->authenticated;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setAuthenticated($authenticated)
|
||||
{
|
||||
$this->authenticated = (Boolean) $authenticated;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function eraseCredentials()
|
||||
{
|
||||
if ($this->getUser() instanceof UserInterface) {
|
||||
$this->getUser()->eraseCredentials();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function serialize()
|
||||
{
|
||||
return serialize(array($this->user, $this->authenticated));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function unserialize($serialized)
|
||||
{
|
||||
list($this->user, $this->authenticated) = unserialize($serialized);
|
||||
}
|
||||
|
||||
private function hasUserChanged(UserInterface $user)
|
||||
{
|
||||
if (!($this->user instanceof UserInterface)) {
|
||||
throw new \BadMethodCallException('Method "hasUserChanged" should be called when current user class is instance of "UserInterface".');
|
||||
}
|
||||
|
||||
if ($this->user instanceof EquatableInterface) {
|
||||
return ! (Boolean) $this->user->isEqualTo($user);
|
||||
}
|
||||
|
||||
if ($this->user->getPassword() !== $user->getPassword()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->user->getSalt() !== $user->getSalt()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->user->getUsername() !== $user->getUsername()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
81
core/lib/Thelia/Core/Security/Token/TokenInterface.php
Normal file
81
core/lib/Thelia/Core/Security/Token/TokenInterface.php
Normal file
@@ -0,0 +1,81 @@
|
||||
<?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\Core\Security\Token;
|
||||
|
||||
/**
|
||||
* TokenInterface is the interface for the user authentication information.
|
||||
*
|
||||
* Parts borrowed from Symfony Security Framework (Fabien Potencier <fabien@symfony.com> / Johannes M. Schmitt <schmittjoh@gmail.com>)
|
||||
*/
|
||||
|
||||
interface TokenInterface extends \Serializable
|
||||
{
|
||||
/**
|
||||
* Returns the user credentials.
|
||||
*
|
||||
* @return mixed The user credentials
|
||||
*/
|
||||
public function getCredentials();
|
||||
|
||||
/**
|
||||
* Returns a user representation.
|
||||
*
|
||||
* @return mixed either returns an object which implements __toString(), or
|
||||
* a primitive string is returned.
|
||||
*/
|
||||
public function getUser();
|
||||
|
||||
/**
|
||||
* Sets a user instance
|
||||
*
|
||||
* @param mixed $user
|
||||
*/
|
||||
public function setUser($user);
|
||||
|
||||
/**
|
||||
* Returns the username.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUsername();
|
||||
|
||||
/**
|
||||
* Returns whether the user is authenticated or not.
|
||||
*
|
||||
* @return Boolean true if the token has been authenticated, false otherwise
|
||||
*/
|
||||
public function isAuthenticated();
|
||||
|
||||
/**
|
||||
* Sets the authenticated flag.
|
||||
*
|
||||
* @param Boolean $isAuthenticated The authenticated flag
|
||||
*/
|
||||
public function setAuthenticated($isAuthenticated);
|
||||
|
||||
/**
|
||||
* Removes sensitive information from the token.
|
||||
*/
|
||||
public function eraseCredentials();
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace Thelia\Core\Security\Token;
|
||||
|
||||
use Thelia\Core\Security\User\UserInterface;
|
||||
|
||||
/**
|
||||
* UsernamePasswordToken implements a username and password token.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class UsernamePasswordToken extends AbstractToken
|
||||
{
|
||||
private $credentials;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $user The username (like a nickname, email address, etc.), or a UserInterface instance or an object implementing a __toString method.
|
||||
* @param string $password The password of the user
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function __construct($username, $password, $authenticated = false)
|
||||
{
|
||||
$this->setUser($username);
|
||||
$this->credentials = $password;
|
||||
|
||||
parent::setAuthenticated($authenticated);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setAuthenticated($isAuthenticated)
|
||||
{
|
||||
if ($isAuthenticated) {
|
||||
throw new \LogicException('Cannot set this token to trusted after instantiation.');
|
||||
}
|
||||
|
||||
parent::setAuthenticated(false);
|
||||
}
|
||||
|
||||
public function getCredentials()
|
||||
{
|
||||
return $this->credentials;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function eraseCredentials()
|
||||
{
|
||||
parent::eraseCredentials();
|
||||
|
||||
$this->credentials = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function serialize()
|
||||
{
|
||||
return serialize(array($this->credentials, $this->providerKey, parent::serialize()));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function unserialize($serialized)
|
||||
{
|
||||
list($this->credentials, $this->providerKey, $parentStr) = unserialize($serialized);
|
||||
parent::unserialize($parentStr);
|
||||
}
|
||||
}
|
||||
18
core/lib/Thelia/Core/Security/User/AdminUserProvider.php
Normal file
18
core/lib/Thelia/Core/Security/User/AdminUserProvider.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
use Thelia\Core\Security\User\UserProviderInterface;
|
||||
use Thelia\Model\Admin;
|
||||
use Thelia\Core\Security\Encoder\PasswordEncoderInterface;
|
||||
|
||||
class AdminUserProvider implements UserProviderInterface {
|
||||
|
||||
public function getUser($key) {
|
||||
|
||||
$admin = new Admin();
|
||||
|
||||
$admin = AdminQuery::create()
|
||||
->filterByLogin($key)
|
||||
->findOne();
|
||||
|
||||
return $admin;
|
||||
}
|
||||
}
|
||||
20
core/lib/Thelia/Core/Security/User/CustomerUserProvider.php
Normal file
20
core/lib/Thelia/Core/Security/User/CustomerUserProvider.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
use Thelia\Core\Security\User\UserProviderInterface;
|
||||
use Thelia\Model\Customer;
|
||||
use Thelia\Model\CustomerQuery;
|
||||
use Thelia\Core\Security\UserNotFoundException;
|
||||
use Thelia\Core\Security\Encoder\PasswordEncoderInterface;
|
||||
|
||||
class CustomerUserProvider implements UserProviderInterface {
|
||||
|
||||
public function getUser($key) {
|
||||
|
||||
$customer = new Customer();
|
||||
|
||||
$customer = CustomerQuery::create()
|
||||
->filterByEmail($key)
|
||||
->findOne();
|
||||
|
||||
return $customer;
|
||||
}
|
||||
}
|
||||
42
core/lib/Thelia/Core/Security/User/UserInterface.php
Normal file
42
core/lib/Thelia/Core/Security/User/UserInterface.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Thelia\Core\Security\User;
|
||||
|
||||
/**
|
||||
* This interface should be implemented by user classes
|
||||
*
|
||||
* @author Franck Allimant <franck@cqfdev.fr>
|
||||
*
|
||||
*/
|
||||
interface UserInterface {
|
||||
|
||||
/**
|
||||
* Return the user unique name
|
||||
*/
|
||||
public function getUsername();
|
||||
|
||||
/**
|
||||
* Return the user encoded password
|
||||
*/
|
||||
public function getPassword();
|
||||
|
||||
/**
|
||||
* return the salt used to calculate the user password
|
||||
*/
|
||||
public function getSalt();
|
||||
|
||||
/**
|
||||
* return the algorithm used to calculate the user password
|
||||
*/
|
||||
public function getAlgo();
|
||||
|
||||
/**
|
||||
* Removes sensitive data from the user.
|
||||
*
|
||||
* This is important if, at any given point, sensitive information like
|
||||
* the plain-text password is stored on this object.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function eraseCredentials();
|
||||
}
|
||||
14
core/lib/Thelia/Core/Security/User/UserProviderInterface.php
Normal file
14
core/lib/Thelia/Core/Security/User/UserProviderInterface.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Thelia\Core\Security\User;
|
||||
|
||||
interface UserProviderInterface {
|
||||
/**
|
||||
* Returns a UserInterface instance
|
||||
*
|
||||
* @param $key the unique user key (username, email address, etc.)
|
||||
* @return a UserInterface instance, or null if none was found.
|
||||
*/
|
||||
public function getUser($key);
|
||||
}
|
||||
?>
|
||||
@@ -68,6 +68,9 @@ abstract class BaseLoop
|
||||
$this->dispatcher = $dispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Thelia\Core\Template\Loop\Argument\ArgumentCollection
|
||||
*/
|
||||
public function getArgs()
|
||||
{
|
||||
return $this->defineArgs()->addArguments($this->getDefaultArgs());
|
||||
|
||||
@@ -29,12 +29,12 @@ class LoopResultRow
|
||||
|
||||
public function set($key, $value)
|
||||
{
|
||||
$this->substitution["#".$key] = $value;
|
||||
$this->substitution[$key] = $value === null ? '' : $value;
|
||||
}
|
||||
|
||||
public function get($key)
|
||||
{
|
||||
return $this->substitution["#".$key];
|
||||
return $this->substitution[$key];
|
||||
}
|
||||
|
||||
public function getVarVal()
|
||||
@@ -42,4 +42,9 @@ class LoopResultRow
|
||||
return $this->substitution;
|
||||
}
|
||||
|
||||
public function getVars()
|
||||
{
|
||||
return array_keys($this->substitution);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -72,6 +72,32 @@ class Argument
|
||||
);
|
||||
}
|
||||
|
||||
public static function createFloatTypeArgument($name, $default=null, $mandatory=false, $empty=true)
|
||||
{
|
||||
return new Argument(
|
||||
$name,
|
||||
new TypeCollection(
|
||||
new Type\FloatType()
|
||||
),
|
||||
$default,
|
||||
$mandatory,
|
||||
$empty
|
||||
);
|
||||
}
|
||||
|
||||
public static function createBooleanTypeArgument($name, $default=null, $mandatory=false, $empty=true)
|
||||
{
|
||||
return new Argument(
|
||||
$name,
|
||||
new TypeCollection(
|
||||
new Type\BooleanType()
|
||||
),
|
||||
$default,
|
||||
$mandatory,
|
||||
$empty
|
||||
);
|
||||
}
|
||||
|
||||
public static function createIntListTypeArgument($name, $default=null, $mandatory=false, $empty=true)
|
||||
{
|
||||
return new Argument(
|
||||
|
||||
@@ -64,6 +64,7 @@ use Thelia\Type;
|
||||
* Class Category
|
||||
* @package Thelia\Core\Template\Loop
|
||||
* @author Manuel Raynaud <mraynaud@openstudio.fr>
|
||||
* @author Etienne Roudeix <eroudeix@openstudio.fr>
|
||||
*/
|
||||
class Category extends BaseLoop
|
||||
{
|
||||
@@ -85,9 +86,9 @@ class Category extends BaseLoop
|
||||
return new ArgumentCollection(
|
||||
Argument::createIntListTypeArgument('id'),
|
||||
Argument::createIntTypeArgument('parent'),
|
||||
Argument::createIntTypeArgument('current'),
|
||||
Argument::createIntTypeArgument('not_empty', 0),
|
||||
Argument::createIntTypeArgument('visible', 1),
|
||||
Argument::createBooleanTypeArgument('current'),
|
||||
Argument::createBooleanTypeArgument('not_empty', 0),
|
||||
Argument::createBooleanTypeArgument('visible', 1),
|
||||
Argument::createAnyTypeArgument('link'),
|
||||
new Argument(
|
||||
'order',
|
||||
@@ -95,7 +96,7 @@ class Category extends BaseLoop
|
||||
new Type\EnumType('alpha', 'alpha_reverse', 'reverse')
|
||||
)
|
||||
),
|
||||
Argument::createIntTypeArgument('random', 0),
|
||||
Argument::createBooleanTypeArgument('random', 0),
|
||||
Argument::createIntListTypeArgument('exclude')
|
||||
);
|
||||
}
|
||||
@@ -110,28 +111,28 @@ class Category extends BaseLoop
|
||||
$search = CategoryQuery::create();
|
||||
|
||||
if (!is_null($this->id)) {
|
||||
$search->filterById(explode(',', $this->id), Criteria::IN);
|
||||
$search->filterById($this->id, Criteria::IN);
|
||||
}
|
||||
|
||||
if (!is_null($this->parent)) {
|
||||
$search->filterByParent($this->parent);
|
||||
}
|
||||
|
||||
if ($this->current == 1) {
|
||||
if ($this->current === true) {
|
||||
$search->filterById($this->request->get("category_id"));
|
||||
} elseif (null !== $this->current && $this->current == 0) {
|
||||
} elseif ($this->current === false) {
|
||||
$search->filterById($this->request->get("category_id"), Criteria::NOT_IN);
|
||||
}
|
||||
|
||||
if (!is_null($this->exclude)) {
|
||||
$search->filterById(explode(",", $this->exclude), Criteria::NOT_IN);
|
||||
$search->filterById($this->exclude, Criteria::NOT_IN);
|
||||
}
|
||||
|
||||
if (!is_null($this->link)) {
|
||||
$search->filterByLink($this->link);
|
||||
}
|
||||
|
||||
$search->filterByVisible($this->visible);
|
||||
$search->filterByVisible($this->visible ? 1 : 0);
|
||||
|
||||
switch ($this->order) {
|
||||
case "alpha":
|
||||
@@ -148,7 +149,7 @@ class Category extends BaseLoop
|
||||
break;
|
||||
}
|
||||
|
||||
if ($this->random == 1) {
|
||||
if ($this->random === true) {
|
||||
$search->clearOrderByColumns();
|
||||
$search->addAscendingOrderByColumn('RAND()');
|
||||
}
|
||||
|
||||
303
core/lib/Thelia/Core/Template/Loop/Product.php
Executable file
303
core/lib/Thelia/Core/Template/Loop/Product.php
Executable file
@@ -0,0 +1,303 @@
|
||||
<?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\Core\Template\Loop;
|
||||
|
||||
use Propel\Runtime\ActiveQuery\Criteria;
|
||||
|
||||
use Thelia\Core\Template\Element\BaseLoop;
|
||||
use Thelia\Core\Template\Element\LoopResult;
|
||||
use Thelia\Core\Template\Element\LoopResultRow;
|
||||
|
||||
use Thelia\Core\Template\Loop\Argument\ArgumentCollection;
|
||||
use Thelia\Core\Template\Loop\Argument\Argument;
|
||||
use Thelia\Log\Tlog;
|
||||
|
||||
use Thelia\Model\CategoryQuery;
|
||||
use Thelia\Model\ProductCategoryQuery;
|
||||
use Thelia\Model\ProductPeer;
|
||||
use Thelia\Model\ProductQuery;
|
||||
use Thelia\Model\ConfigQuery;
|
||||
use Thelia\Type\TypeCollection;
|
||||
use Thelia\Type;
|
||||
|
||||
/**
|
||||
*
|
||||
* Product loop
|
||||
*
|
||||
*
|
||||
* Class Product
|
||||
* @package Thelia\Core\Template\Loop
|
||||
* @author Etienne Roudeix <eroudeix@openstudio.fr>
|
||||
*/
|
||||
class Product extends BaseLoop
|
||||
{
|
||||
public $id;
|
||||
public $ref;
|
||||
public $category;
|
||||
public $new;
|
||||
public $promo;
|
||||
public $min_price;
|
||||
public $max_price;
|
||||
public $min_stock;
|
||||
public $min_weight;
|
||||
public $max_weight;
|
||||
public $current;
|
||||
public $current_category;
|
||||
public $depth;
|
||||
public $visible;
|
||||
public $order;
|
||||
public $random;
|
||||
public $exclude;
|
||||
|
||||
/**
|
||||
* @return ArgumentCollection
|
||||
*/
|
||||
protected function defineArgs()
|
||||
{
|
||||
return new ArgumentCollection(
|
||||
Argument::createIntListTypeArgument('id'),
|
||||
new Argument(
|
||||
'ref',
|
||||
new TypeCollection(
|
||||
new Type\AlphaNumStringListType()
|
||||
)
|
||||
),
|
||||
Argument::createIntListTypeArgument('category'),
|
||||
Argument::createBooleanTypeArgument('new'),
|
||||
Argument::createBooleanTypeArgument('promo'),
|
||||
Argument::createFloatTypeArgument('min_price'),
|
||||
Argument::createFloatTypeArgument('max_price'),
|
||||
Argument::createIntTypeArgument('min_stock'),
|
||||
Argument::createFloatTypeArgument('min_weight'),
|
||||
Argument::createFloatTypeArgument('max_weight'),
|
||||
Argument::createBooleanTypeArgument('current'),
|
||||
Argument::createBooleanTypeArgument('current_category'),
|
||||
Argument::createIntTypeArgument('depth'),
|
||||
Argument::createBooleanTypeArgument('visible', 1),
|
||||
new Argument(
|
||||
'order',
|
||||
new TypeCollection(
|
||||
new Type\EnumType(array('alpha', 'alpha_reverse', 'reverse', 'min_price', 'max_price', 'category', 'manual', 'manual_reverse', 'ref', 'promo', 'new'))
|
||||
)
|
||||
),
|
||||
Argument::createBooleanTypeArgument('random', 0),
|
||||
Argument::createIntListTypeArgument('exclude')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $pagination
|
||||
*
|
||||
* @return \Thelia\Core\Template\Element\LoopResult
|
||||
*/
|
||||
public function exec(&$pagination)
|
||||
{
|
||||
$search = ProductQuery::create();
|
||||
|
||||
if (!is_null($this->id)) {
|
||||
$search->filterById($this->id, Criteria::IN);
|
||||
}
|
||||
|
||||
if (!is_null($this->ref)) {
|
||||
$search->filterByRef($this->ref, Criteria::IN);
|
||||
}
|
||||
|
||||
if (!is_null($this->category)) {
|
||||
$categories = CategoryQuery::create()->filterById($this->category, Criteria::IN)->find();
|
||||
|
||||
if(null !== $this->depth) {
|
||||
foreach(CategoryQuery::findAllChild($this->category, $this->depth) as $subCategory) {
|
||||
$categories->prepend($subCategory);
|
||||
}
|
||||
}
|
||||
|
||||
$search->filterByCategory(
|
||||
$categories,
|
||||
Criteria::IN
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->new === true) {
|
||||
$search->filterByNewness(1, Criteria::EQUAL);
|
||||
} else if($this->new === false) {
|
||||
$search->filterByNewness(0, Criteria::EQUAL);
|
||||
}
|
||||
|
||||
if ($this->promo === true) {
|
||||
$search->filterByPromo(1, Criteria::EQUAL);
|
||||
} else if($this->promo === false) {
|
||||
$search->filterByNewness(0, Criteria::EQUAL);
|
||||
}
|
||||
|
||||
if (null != $this->min_stock) {
|
||||
$search->filterByQuantity($this->min_stock, Criteria::GREATER_EQUAL);
|
||||
}
|
||||
|
||||
if(null !== $this->min_price) {
|
||||
$search->condition('in_promo', ProductPeer::PROMO . Criteria::EQUAL . '1')
|
||||
->condition('not_in_promo', ProductPeer::PROMO . Criteria::NOT_EQUAL . '1')
|
||||
->condition('min_price2', ProductPeer::PRICE2 . Criteria::GREATER_EQUAL . '?', $this->min_price)
|
||||
->condition('min_price', ProductPeer::PRICE . Criteria::GREATER_EQUAL . '?', $this->min_price)
|
||||
->combine(array('in_promo', 'min_price2'), Criteria::LOGICAL_AND, 'in_promo_min_price')
|
||||
->combine(array('not_in_promo', 'min_price'), Criteria::LOGICAL_AND, 'not_in_promo_min_price')
|
||||
->where(array('not_in_promo_min_price', 'in_promo_min_price'), Criteria::LOGICAL_OR);
|
||||
}
|
||||
|
||||
if(null !== $this->max_price) {
|
||||
$search->condition('in_promo', ProductPeer::PROMO . Criteria::EQUAL . '1')
|
||||
->condition('not_in_promo', ProductPeer::PROMO . Criteria::NOT_EQUAL . '1')
|
||||
->condition('max_price2', ProductPeer::PRICE2 . Criteria::LESS_EQUAL . '?', $this->max_price)
|
||||
->condition('max_price', ProductPeer::PRICE . Criteria::LESS_EQUAL . '?', $this->max_price)
|
||||
->combine(array('in_promo', 'max_price2'), Criteria::LOGICAL_AND, 'in_promo_max_price')
|
||||
->combine(array('not_in_promo', 'max_price'), Criteria::LOGICAL_AND, 'not_in_promo_max_price')
|
||||
->where(array('not_in_promo_max_price', 'in_promo_max_price'), Criteria::LOGICAL_OR);
|
||||
}
|
||||
|
||||
if(null !== $this->min_weight) {
|
||||
$search->filterByWeight($this->min_weight, Criteria::GREATER_EQUAL);
|
||||
}
|
||||
|
||||
if(null !== $this->max_weight) {
|
||||
$search->filterByWeight($this->max_weight, Criteria::LESS_EQUAL);
|
||||
}
|
||||
|
||||
if ($this->current === true) {
|
||||
$search->filterById($this->request->get("product_id"));
|
||||
} elseif($this->current === false) {
|
||||
$search->filterById($this->request->get("product_id"), Criteria::NOT_IN);
|
||||
}
|
||||
|
||||
if ($this->current_category === true) {
|
||||
$search->filterByCategory(
|
||||
CategoryQuery::create()->filterByProduct(
|
||||
ProductCategoryQuery::create()->filterByProductId(
|
||||
$this->request->get("product_id"),
|
||||
Criteria::EQUAL
|
||||
)->find(),
|
||||
Criteria::IN
|
||||
)->find(),
|
||||
Criteria::IN
|
||||
);
|
||||
} elseif($this->current_category === false) {
|
||||
$search->filterByCategory(
|
||||
CategoryQuery::create()->filterByProduct(
|
||||
ProductCategoryQuery::create()->filterByProductId(
|
||||
$this->request->get("product_id"),
|
||||
Criteria::EQUAL
|
||||
)->find(),
|
||||
Criteria::IN
|
||||
)->find(),
|
||||
Criteria::NOT_IN
|
||||
);
|
||||
}
|
||||
|
||||
$search->filterByVisible($this->visible);
|
||||
|
||||
switch ($this->order) {
|
||||
case "alpha":
|
||||
$search->addAscendingOrderByColumn(\Thelia\Model\CategoryI18nPeer::TITLE);
|
||||
break;
|
||||
case "alpha_reverse":
|
||||
$search->addDescendingOrderByColumn(\Thelia\Model\CategoryI18nPeer::TITLE);
|
||||
break;
|
||||
case "reverse":
|
||||
$search->orderByPosition(Criteria::DESC);
|
||||
break;
|
||||
case "min_price":
|
||||
//$search->order
|
||||
//$search->orderByPosition(Criteria::DESC);
|
||||
break;
|
||||
/*case "max_price":
|
||||
$search->orderByPosition(Criteria::DESC);
|
||||
break;
|
||||
case "category":
|
||||
$search->orderByPosition(Criteria::DESC);
|
||||
break;*/
|
||||
case "manual":
|
||||
$search->addAscendingOrderByColumn(\Thelia\Model\ProductPeer::POSITION);
|
||||
break;
|
||||
case "manual_reverse":
|
||||
$search->addDescendingOrderByColumn(\Thelia\Model\ProductPeer::POSITION);
|
||||
break;
|
||||
case "ref":
|
||||
$search->addAscendingOrderByColumn(\Thelia\Model\ProductPeer::REF);
|
||||
break;
|
||||
case "promo":
|
||||
$search->addDescendingOrderByColumn(\Thelia\Model\ProductPeer::PROMO);
|
||||
break;
|
||||
case "new":
|
||||
$search->addDescendingOrderByColumn(\Thelia\Model\ProductPeer::NEWNESS);
|
||||
break;
|
||||
default:
|
||||
$search->orderByPosition();
|
||||
break;
|
||||
}
|
||||
|
||||
if ($this->random === true) {
|
||||
$search->clearOrderByColumns();
|
||||
$search->addAscendingOrderByColumn('RAND()');
|
||||
}
|
||||
|
||||
if (!is_null($this->exclude)) {
|
||||
$search->filterById($this->exclude, Criteria::NOT_IN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Criteria::INNER_JOIN in second parameter for joinWithI18n exclude query without translation.
|
||||
*
|
||||
* @todo : verify here if we want results for row without translations.
|
||||
*/
|
||||
|
||||
$search->joinWithI18n(
|
||||
$this->request->getSession()->get('locale', 'en_US'),
|
||||
(ConfigQuery::read("default_lang_without_translation", 1)) ? Criteria::LEFT_JOIN : Criteria::INNER_JOIN
|
||||
);
|
||||
|
||||
$products = $this->search($search, $pagination);
|
||||
|
||||
$loopResult = new LoopResult();
|
||||
|
||||
foreach ($products as $product) {
|
||||
$loopResultRow = new LoopResultRow();
|
||||
$loopResultRow->set("ID", $product->getId());
|
||||
$loopResultRow->set("REF",$product->getRef());
|
||||
$loopResultRow->set("TITLE",$product->getTitle());
|
||||
$loopResultRow->set("CHAPO", $product->getChapo());
|
||||
$loopResultRow->set("DESCRIPTION", $product->getDescription());
|
||||
$loopResultRow->set("POSTSCRIPTUM", $product->getPostscriptum());
|
||||
$loopResultRow->set("PRICE", $product->getPrice());
|
||||
$loopResultRow->set("PROMO_PRICE", $product->getPrice2());
|
||||
$loopResultRow->set("WEIGHT", $product->getWeight());
|
||||
$loopResultRow->set("PROMO", $product->getPromo());
|
||||
$loopResultRow->set("NEW", $product->getNewness());
|
||||
|
||||
//$loopResultRow->set("URL", $product->getUrl());
|
||||
|
||||
$loopResult->addRow($loopResultRow);
|
||||
}
|
||||
|
||||
return $loopResult;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -35,7 +35,7 @@ class Assetic implements SmartyPluginInterface
|
||||
{
|
||||
$web_root = THELIA_WEB_DIR;
|
||||
|
||||
$asset_dir_from_web_root = '/assets/admin/default'; // FIXME
|
||||
$asset_dir_from_web_root = 'assets/admin/default'; // FIXME
|
||||
|
||||
$this->asset_manager = new SmartyAssetsManager($web_root, $asset_dir_from_web_root);
|
||||
}
|
||||
|
||||
@@ -43,6 +43,9 @@ class TheliaLoop implements SmartyPluginInterface
|
||||
|
||||
protected $dispatcher;
|
||||
|
||||
protected $loopstack = array();
|
||||
protected $varstack = array();
|
||||
|
||||
public function __construct(Request $request, EventDispatcherInterface $dispatcher)
|
||||
{
|
||||
$this->request = $request;
|
||||
@@ -78,13 +81,16 @@ class TheliaLoop implements SmartyPluginInterface
|
||||
if (empty($params['name']))
|
||||
throw new \InvalidArgumentException("Missing 'name' parameter in loop arguments");
|
||||
|
||||
|
||||
if (empty($params['type']))
|
||||
throw new \InvalidArgumentException("Missing 'type' parameter in loop arguments");
|
||||
|
||||
$name = $params['name'];
|
||||
|
||||
if ($content === null) {
|
||||
// Check if a loop with the same name exists in the current scope, and abort if it's the case.
|
||||
if (array_key_exists($name, $this->varstack)) {
|
||||
throw new \InvalidArgumentException("A loop named '$name' already exists in the current scope.");
|
||||
}
|
||||
|
||||
$loop = $this->createLoopInstance(strtolower($params['type']));
|
||||
|
||||
@@ -93,11 +99,10 @@ class TheliaLoop implements SmartyPluginInterface
|
||||
self::$pagination[$name] = null;
|
||||
|
||||
$loopResults = $loop->exec(self::$pagination[$name]);
|
||||
|
||||
$template->assignByRef($name, $loopResults);
|
||||
$this->loopstack[$name] = $loopResults;
|
||||
|
||||
} else {
|
||||
$loopResults = $template->getTemplateVars($name);
|
||||
$loopResults = $this->loopstack[$name];
|
||||
|
||||
$loopResults->next();
|
||||
}
|
||||
@@ -105,21 +110,50 @@ class TheliaLoop implements SmartyPluginInterface
|
||||
if ($loopResults->valid()) {
|
||||
$loopResultRow = $loopResults->current();
|
||||
|
||||
foreach($loopResultRow->getVarVal() as $var => $val) {
|
||||
$template->assign(substr($var, 1), $val);
|
||||
// On first iteration, save variables that may be overwritten by this loop
|
||||
if (! isset($this->varstack[$name])) {
|
||||
|
||||
$saved_vars = array();
|
||||
|
||||
$varlist = $loopResultRow->getVars();
|
||||
$varlist[] = 'LOOP_COUNT';
|
||||
$varlist[] = 'LOOP_TOTAL';
|
||||
|
||||
foreach($varlist as $var) {
|
||||
$saved_vars[$var] = $template->getTemplateVars($var);
|
||||
}
|
||||
|
||||
$template->assign('__COUNT__', 1 + $loopResults->key());
|
||||
$template->assign('__TOTAL__', $loopResults->getCount());
|
||||
$this->varstack[$name] = $saved_vars;
|
||||
}
|
||||
|
||||
foreach($loopResultRow->getVarVal() as $var => $val) {
|
||||
$template->assign($var, $val);
|
||||
}
|
||||
|
||||
//$repeat = $loopResults->valid();
|
||||
$repeat = true;
|
||||
}
|
||||
|
||||
// Assign meta information
|
||||
$template->assign('LOOP_COUNT', 1 + $loopResults->key());
|
||||
$template->assign('LOOP_TOTAL', $loopResults->getCount());
|
||||
|
||||
// Loop is terminated. Cleanup.
|
||||
if (! $repeat) {
|
||||
// Restore previous variables values before terminating
|
||||
if (isset($this->varstack[$name])) {
|
||||
foreach($this->varstack[$name] as $var => $value) {
|
||||
$template->assign($var, $value);
|
||||
}
|
||||
|
||||
unset($this->varstack[$name]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($content !== null) {
|
||||
if ($loopResults->isEmpty()) {
|
||||
$content = "";
|
||||
}
|
||||
|
||||
if ($loopResults->isEmpty()) $content = "";
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
@@ -178,10 +212,10 @@ class TheliaLoop implements SmartyPluginInterface
|
||||
$loopName = $params['rel'];
|
||||
|
||||
// Find loop results in the current template vars
|
||||
$loopResults = $template->getTemplateVars($loopName);
|
||||
/* $loopResults = $template->getTemplateVars($loopName);
|
||||
if (empty($loopResults)) {
|
||||
throw new \InvalidArgumentException("Loop $loopName is not defined.");
|
||||
}
|
||||
}*/
|
||||
|
||||
// Find pagination
|
||||
$pagination = self::getPagination($loopName);
|
||||
@@ -225,14 +259,11 @@ class TheliaLoop implements SmartyPluginInterface
|
||||
|
||||
$loopName = $params['rel'];
|
||||
|
||||
// Find loop results in the current template vars
|
||||
$loopResults = $template->getTemplateVars($loopName);
|
||||
|
||||
if (empty($loopResults)) {
|
||||
if (! isset($this->loopstack[$loopName])) {
|
||||
throw new \InvalidArgumentException("Loop $loopName is not defined.");
|
||||
}
|
||||
|
||||
return $loopResults->isEmpty();
|
||||
return $this->loopstack[$loopName]->isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -279,7 +310,7 @@ class TheliaLoop implements SmartyPluginInterface
|
||||
$argumentsCollection = $loop->getArgs();
|
||||
foreach( $argumentsCollection as $argument ) {
|
||||
|
||||
$value = isset($smartyParam[$argument->name]) ? $smartyParam[$argument->name] : null;
|
||||
$value = isset($smartyParam[$argument->name]) ? (string)$smartyParam[$argument->name] : null;
|
||||
|
||||
/* check if mandatory */
|
||||
if($value === null && $argument->mandatory) {
|
||||
@@ -304,11 +335,11 @@ class TheliaLoop implements SmartyPluginInterface
|
||||
|
||||
/* set default */
|
||||
/* did it as last checking for we consider default value is acceptable no matter type or empty restriction */
|
||||
if($value === null) {
|
||||
$value = $argument->default;
|
||||
if($value === null && $argument->default !== null) {
|
||||
$value = (string)$argument->default;
|
||||
}
|
||||
|
||||
$loop->{$argument->name} = $value;
|
||||
$loop->{$argument->name} = $value === null ? null : $argument->type->getFormatedValue($value);
|
||||
}
|
||||
|
||||
if (!empty($faultActor)) {
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
<?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\Core\Template\Smarty\Plugins;
|
||||
|
||||
use Thelia\Core\Template\Smarty\SmartyPluginDescriptor;
|
||||
use Thelia\Core\Template\Smarty\SmartyPluginInterface;
|
||||
|
||||
/**
|
||||
* Class TheliaSyntax
|
||||
* @package Thelia\Core\Template\Smarty\Plugins
|
||||
*
|
||||
* @author Etienne Roudeix <eroudeix@openstudio.fr>
|
||||
*/
|
||||
class TheliaSyntax implements SmartyPluginInterface
|
||||
{
|
||||
public function dieseCancel($value, $diese)
|
||||
{
|
||||
if($value === null) {
|
||||
return $diese;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return SmartyPluginDescriptor[]
|
||||
*/
|
||||
public function getPluginDescriptors()
|
||||
{
|
||||
return array(
|
||||
new SmartyPluginDescriptor("modifier", "dieseCanceller", $this, "dieseCancel")
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,7 @@ class Translation implements SmartyPluginInterface
|
||||
}
|
||||
|
||||
// TODO
|
||||
return "[$string]";
|
||||
return "$string";
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,10 +29,11 @@ class SmartyParser extends Smarty implements ParserInterface
|
||||
protected $status = 200;
|
||||
|
||||
/**
|
||||
* @param \Symfony\Component\HttpFoundation\Request $request
|
||||
* @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $dispatcher
|
||||
* @param Request $request
|
||||
* @param EventDispatcherInterface $dispatcher
|
||||
* @param bool $template
|
||||
* @param string $env Environment define for the kernel application. Used for the cache directory
|
||||
* @param string $env
|
||||
* @param bool $debug
|
||||
*/
|
||||
public function __construct(Request $request, EventDispatcherInterface $dispatcher, $template = false, $env = "prod", $debug = false)
|
||||
{
|
||||
@@ -72,13 +73,13 @@ class SmartyParser extends Smarty implements ParserInterface
|
||||
// The default HTTP status
|
||||
$this->status = 200;
|
||||
|
||||
$this->registerFilter('pre', array($this, "pretest"));
|
||||
$this->registerFilter('pre', array($this, "preThelia"));
|
||||
}
|
||||
|
||||
public function pretest($tpl_source, \Smarty_Internal_Template $template)
|
||||
public function preThelia($tpl_source, \Smarty_Internal_Template $template)
|
||||
{
|
||||
$new_source = preg_replace('`{#([a-zA-Z][a-zA-Z0-9\-_]*)(.*)}`', '{\$$1$2}', $tpl_source);
|
||||
$new_source = preg_replace('`#([a-zA-Z][a-zA-Z0-9\-_]*)`', '{\$$1|default:\'#$1\'}', $new_source);
|
||||
$new_source = preg_replace('`#([a-zA-Z][a-zA-Z0-9\-_]*)`', '{\$$1|dieseCanceller:\'#$1\'}', $new_source);
|
||||
|
||||
return $new_source;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace Thelia\Form;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Validator\Constraints\Length;
|
||||
use Symfony\Component\Validator\Constraints\NotBlank;
|
||||
use Symfony\Component\Validator\Constraints\Choice;
|
||||
|
||||
class AdminLogin extends BaseForm {
|
||||
|
||||
@@ -38,7 +39,12 @@ class AdminLogin extends BaseForm {
|
||||
new Length(array("min" => 3))
|
||||
)
|
||||
))
|
||||
->add("password", "password");
|
||||
->add("password", "password", array(
|
||||
"constraints" => array(
|
||||
new NotBlank()
|
||||
)
|
||||
))
|
||||
->add("remember_me", "checkbox");
|
||||
}
|
||||
|
||||
public function getName()
|
||||
|
||||
@@ -32,7 +32,7 @@ class CategoryQuery extends BaseCategoryQuery {
|
||||
*
|
||||
* find all category children for a given category. an array of \Thelia\Model\Category is return
|
||||
*
|
||||
* @param $categoryId the category id
|
||||
* @param $categoryId the category id or an array of id
|
||||
* @param int $depth max depth you want to search
|
||||
* @param int $currentPos don't change this param, it is used for recursion
|
||||
* @return \Thelia\Model\Category[]
|
||||
@@ -40,6 +40,12 @@ class CategoryQuery extends BaseCategoryQuery {
|
||||
public static function findAllChild($categoryId, $depth = 0, $currentPos = 0)
|
||||
{
|
||||
$result = array();
|
||||
|
||||
if(is_array($categoryId)) {
|
||||
foreach($categoryId as $categorySingleId) {
|
||||
$result = array_merge($result, (array) self::findAllChild($categorySingleId, $depth, $currentPos));
|
||||
}
|
||||
} else {
|
||||
$currentPos++;
|
||||
|
||||
if($depth == $currentPos && $depth != 0) return;
|
||||
@@ -48,10 +54,12 @@ class CategoryQuery extends BaseCategoryQuery {
|
||||
->filterByParent($categoryId)
|
||||
->find();
|
||||
|
||||
|
||||
foreach ($categories as $category) {
|
||||
array_push($result, $category);
|
||||
$result = array_merge($result, (array) self::findAllChild($category->getId(), $depth, $currentPos));
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
use Thelia\Core\Security\Encoder\PasswordHashEncoder;
|
||||
|
||||
class PasswordHashEncoderTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testEncode()
|
||||
{
|
||||
$encoder = new PasswordHashEncoder();
|
||||
|
||||
$pass = $encoder->encode('password', 'sha512', 'a simple salt');
|
||||
|
||||
// echo "PASS=\{$pass\}";
|
||||
|
||||
$this->assertEquals("L3f/gGy4nBVhi8WSsC1a7E9JM8U+rtk6ZT+NiqX8M1UDJv6mahQEZ1z2cN/y9pixH+hgWbkBitONMiXWscomoQ==", $pass, "Expected password not found.");
|
||||
}
|
||||
|
||||
public function testIsEqual()
|
||||
{
|
||||
$encoder = new PasswordHashEncoder();
|
||||
|
||||
$exp = "L3f/gGy4nBVhi8WSsC1a7E9JM8U+rtk6ZT+NiqX8M1UDJv6mahQEZ1z2cN/y9pixH+hgWbkBitONMiXWscomoQ==";
|
||||
|
||||
$this->assertTrue($encoder->isEqual($exp, 'password', 'sha512', 'a simple salt'));
|
||||
}
|
||||
|
||||
public function testWrongPass()
|
||||
{
|
||||
$encoder = new PasswordHashEncoder();
|
||||
|
||||
$exp = "L3f/gGy4nBVhi8WSsC1a7E9JM8U+rtk6ZT+NiqX8M1UDJv6mahQEZ1z2cN/y9pixH+hgWbkBitONMiXWscomoQ==";
|
||||
|
||||
$this->assertFalse($encoder->isEqual($exp, 'grongron', 'sha512', 'a simple salt'));
|
||||
}
|
||||
|
||||
public function testWrongSalt()
|
||||
{
|
||||
$encoder = new PasswordHashEncoder();
|
||||
|
||||
$exp = "L3f/gGy4nBVhi8WSsC1a7E9JM8U+rtk6ZT+NiqX8M1UDJv6mahQEZ1z2cN/y9pixH+hgWbkBitONMiXWscomoQ==";
|
||||
|
||||
$this->assertFalse($encoder->isEqual($exp, 'password', 'sha512', 'another salt'));
|
||||
}
|
||||
|
||||
public function testWrongAlgo()
|
||||
{
|
||||
$encoder = new PasswordHashEncoder();
|
||||
|
||||
$exp = "L3f/gGy4nBVhi8WSsC1a7E9JM8U+rtk6ZT+NiqX8M1UDJv6mahQEZ1z2cN/y9pixH+hgWbkBitONMiXWscomoQ==";
|
||||
|
||||
$this->assertFalse($encoder->isEqual($exp, 'password', 'md5', 'another salt'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException LogicException
|
||||
*/
|
||||
public function testUnsupportedAlgo()
|
||||
{
|
||||
$encoder = new PasswordHashEncoder();
|
||||
|
||||
$exp = "L3f/gGy4nBVhi8WSsC1a7E9JM8U+rtk6ZT+NiqX8M1UDJv6mahQEZ1z2cN/y9pixH+hgWbkBitONMiXWscomoQ==";
|
||||
|
||||
$encoder->isEqual($exp, 'password', 'sbonk', 'another salt');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException LogicException
|
||||
*/
|
||||
public function testEncodeWrongAlgorithm()
|
||||
{
|
||||
$encoder = new PasswordHashEncoder();
|
||||
|
||||
$encoder->encode('password', 'pouët', 'a simple salt');
|
||||
}
|
||||
}
|
||||
49
core/lib/Thelia/Tests/Core/Security/SecurityManagerTest.php
Normal file
49
core/lib/Thelia/Tests/Core/Security/SecurityManagerTest.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?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\Tests\Security;
|
||||
|
||||
use Thelia\Core\Security\SecurityManager;
|
||||
/**
|
||||
*
|
||||
* @author Franck Allimant <franck@cqfdev.fr>
|
||||
*
|
||||
*/
|
||||
class SecurityManagerTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testGetSetToken()
|
||||
{
|
||||
/*
|
||||
$context = new SecurityManager($authProvider)(
|
||||
$this->getMock('AuthenticationProviderInterface'),
|
||||
$this->getMock('Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface')
|
||||
);
|
||||
$this->assertNull($context->getToken());
|
||||
|
||||
$context->setToken($token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface'));
|
||||
$this->assertSame($token, $context->getToken());
|
||||
*/
|
||||
// $this->assertFalse(1==1, "faux !");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
use Thelia\Core\Security\Token\UsernamePasswordToken;
|
||||
|
||||
class UsernamePasswordTokenTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testConstructor()
|
||||
{
|
||||
$token = new UsernamePasswordToken('username', 'password');
|
||||
|
||||
$this->assertFalse($token->isAuthenticated());
|
||||
|
||||
$token = new UsernamePasswordToken('username', 'password', true);
|
||||
$this->assertTrue($token->isAuthenticated());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException LogicException
|
||||
*/
|
||||
public function testSetAuthenticatedToTrue()
|
||||
{
|
||||
$token = new UsernamePasswordToken('foo', 'bar', true);
|
||||
$token->setAuthenticated(true);
|
||||
}
|
||||
|
||||
public function testSetAuthenticatedToFalse()
|
||||
{
|
||||
$token = new UsernamePasswordToken('foo', 'bar', true);
|
||||
$token->setAuthenticated(false);
|
||||
$this->assertFalse($token->isAuthenticated());
|
||||
}
|
||||
|
||||
public function testEraseCredentials()
|
||||
{
|
||||
$token = new UsernamePasswordToken('foo', 'bar', true);
|
||||
$token->eraseCredentials();
|
||||
$this->assertEquals('', $token->getCredentials());
|
||||
}
|
||||
}
|
||||
48
core/lib/Thelia/Tests/Type/AlphaNumStringListTypeTest.php
Executable file
48
core/lib/Thelia/Tests/Type/AlphaNumStringListTypeTest.php
Executable file
@@ -0,0 +1,48 @@
|
||||
<?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\Tests\Type;
|
||||
|
||||
use Thelia\Type\AlphaNumStringListType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Etienne Roudeix <eroudeix@openstudio.fr>
|
||||
*
|
||||
*/
|
||||
class AlphaNumStringListTypeTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testAlphaNumStringListType()
|
||||
{
|
||||
$type = new AlphaNumStringListType();
|
||||
$this->assertTrue($type->isValid('FOO1,FOO_2,FOO-3'));
|
||||
$this->assertFalse($type->isValid('FOO.1,FOO$_2,FOO-3'));
|
||||
}
|
||||
|
||||
public function testFormatAlphaNumStringListType()
|
||||
{
|
||||
$type = new AlphaNumStringListType();
|
||||
$this->assertTrue(is_array($type->getFormatedValue('FOO1,FOO_2,FOO-3')));
|
||||
$this->assertNull($type->getFormatedValue('5€'));
|
||||
}
|
||||
}
|
||||
43
core/lib/Thelia/Tests/Type/AlphaNumStringTypeTest.php
Executable file
43
core/lib/Thelia/Tests/Type/AlphaNumStringTypeTest.php
Executable file
@@ -0,0 +1,43 @@
|
||||
<?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\Tests\Type;
|
||||
|
||||
use Thelia\Type\AlphaNumStringType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Etienne Roudeix <eroudeix@openstudio.fr>
|
||||
*
|
||||
*/
|
||||
class AlphaNumStringTypeTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testAlphaNumStringType()
|
||||
{
|
||||
$type = new AlphaNumStringType();
|
||||
$this->assertTrue($type->isValid('azs_qs-0-9ds'));
|
||||
$this->assertFalse($type->isValid('3.3'));
|
||||
$this->assertFalse($type->isValid('3 3'));
|
||||
$this->assertFalse($type->isValid('3€3'));
|
||||
}
|
||||
}
|
||||
55
core/lib/Thelia/Tests/Type/BooleanTypeTest.php
Executable file
55
core/lib/Thelia/Tests/Type/BooleanTypeTest.php
Executable file
@@ -0,0 +1,55 @@
|
||||
<?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\Tests\Type;
|
||||
|
||||
use Thelia\Type\BooleanType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Etienne Roudeix <eroudeix@openstudio.fr>
|
||||
*
|
||||
*/
|
||||
class BooleanTypeTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testBooleanType()
|
||||
{
|
||||
$booleanType = new BooleanType();
|
||||
$this->assertTrue($booleanType->isValid('y'));
|
||||
$this->assertTrue($booleanType->isValid('yes'));
|
||||
$this->assertTrue($booleanType->isValid('true'));
|
||||
$this->assertTrue($booleanType->isValid('no'));
|
||||
$this->assertTrue($booleanType->isValid('n'));
|
||||
$this->assertTrue($booleanType->isValid('false'));
|
||||
$this->assertFalse($booleanType->isValid('foo'));
|
||||
$this->assertFalse($booleanType->isValid(5));
|
||||
}
|
||||
|
||||
public function testFormatBooleanType()
|
||||
{
|
||||
$booleanType = new BooleanType();
|
||||
$this->assertTrue($booleanType->getFormatedValue('yes'));
|
||||
$this->assertFalse($booleanType->getFormatedValue('no'));
|
||||
$this->assertNull($booleanType->getFormatedValue('foo'));
|
||||
}
|
||||
}
|
||||
@@ -39,4 +39,11 @@ class IntListTypeTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertTrue($intListType->isValid('1,2,3'));
|
||||
$this->assertFalse($intListType->isValid('1,2,3.3'));
|
||||
}
|
||||
|
||||
public function testFormatIntListType()
|
||||
{
|
||||
$intListType = new IntListType();
|
||||
$this->assertTrue(is_array($intListType->getFormatedValue('1,2,3')));
|
||||
$this->assertNull($intListType->getFormatedValue('foo'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,4 +38,11 @@ class JsonTypeTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertTrue($jsonType->isValid('{"k0":"v0","k1":"v1","k2":"v2"}'));
|
||||
$this->assertFalse($jsonType->isValid('1,2,3'));
|
||||
}
|
||||
|
||||
public function testFormatJsonType()
|
||||
{
|
||||
$jsonType = new JsonType();
|
||||
$this->assertTrue(is_array($jsonType->getFormatedValue('{"k0":"v0","k1":"v1","k2":"v2"}')));
|
||||
$this->assertNull($jsonType->getFormatedValue('foo'));
|
||||
}
|
||||
}
|
||||
|
||||
52
core/lib/Thelia/Type/AlphaNumStringListType.php
Executable file
52
core/lib/Thelia/Type/AlphaNumStringListType.php
Executable file
@@ -0,0 +1,52 @@
|
||||
<?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\Type;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Etienne Roudeix <eroudeix@openstudio.fr>
|
||||
*
|
||||
*/
|
||||
|
||||
class AlphaNumStringListType implements TypeInterface
|
||||
{
|
||||
public function getType()
|
||||
{
|
||||
return 'Alphanumeric string list type';
|
||||
}
|
||||
|
||||
public function isValid($values)
|
||||
{
|
||||
foreach(explode(',', $values) as $value) {
|
||||
if(!preg_match('#^[a-zA-Z0-9\-_]+$#', $value))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getFormatedValue($values)
|
||||
{
|
||||
return $this->isValid($values) ? explode(',', $values) : null;
|
||||
}
|
||||
}
|
||||
47
core/lib/Thelia/Type/AlphaNumStringType.php
Executable file
47
core/lib/Thelia/Type/AlphaNumStringType.php
Executable file
@@ -0,0 +1,47 @@
|
||||
<?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\Type;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Etienne Roudeix <eroudeix@openstudio.fr>
|
||||
*
|
||||
*/
|
||||
|
||||
class AlphaNumStringType implements TypeInterface
|
||||
{
|
||||
public function getType()
|
||||
{
|
||||
return 'Alphanumeric string type';
|
||||
}
|
||||
|
||||
public function isValid($value)
|
||||
{
|
||||
return preg_match('#^[a-zA-Z0-9\-_]+$#', $value) ? true : false;
|
||||
}
|
||||
|
||||
public function getFormatedValue($value)
|
||||
{
|
||||
return $this->isValid($value) ? $value : null;
|
||||
}
|
||||
}
|
||||
@@ -39,4 +39,9 @@ class AnyType implements TypeInterface
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getFormatedValue($value)
|
||||
{
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
60
core/lib/Thelia/Type/BooleanType.php
Executable file
60
core/lib/Thelia/Type/BooleanType.php
Executable file
@@ -0,0 +1,60 @@
|
||||
<?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\Type;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Etienne Roudeix <eroudeix@openstudio.fr>
|
||||
*
|
||||
*/
|
||||
|
||||
class BooleanType implements TypeInterface
|
||||
{
|
||||
protected $trueValuesArray = array(
|
||||
'1',
|
||||
'true',
|
||||
'yes',
|
||||
'y',
|
||||
);
|
||||
protected $falseValuesArray = array(
|
||||
'0',
|
||||
'false',
|
||||
'no',
|
||||
'n',
|
||||
);
|
||||
|
||||
public function getType()
|
||||
{
|
||||
return 'Boolean type';
|
||||
}
|
||||
|
||||
public function isValid($value)
|
||||
{
|
||||
return in_array($value, $this->trueValuesArray) || in_array($value, $this->falseValuesArray);
|
||||
}
|
||||
|
||||
public function getFormatedValue($value)
|
||||
{
|
||||
return $this->isValid($value) ? ( in_array($value, $this->trueValuesArray) ) : null;
|
||||
}
|
||||
}
|
||||
@@ -47,4 +47,9 @@ class EnumType implements TypeInterface
|
||||
{
|
||||
return in_array($value, $this->values);
|
||||
}
|
||||
|
||||
public function getFormatedValue($value)
|
||||
{
|
||||
return $this->isValid($value) ? $value : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,4 +39,9 @@ class FloatType implements TypeInterface
|
||||
{
|
||||
return filter_var($value, FILTER_VALIDATE_FLOAT) === false ? false : true;
|
||||
}
|
||||
|
||||
public function getFormatedValue($value)
|
||||
{
|
||||
return $this->isValid($value) ? $value : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,4 +44,9 @@ class IntListType implements TypeInterface
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getFormatedValue($values)
|
||||
{
|
||||
return $this->isValid($values) ? explode(',', $values) : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,4 +39,9 @@ class IntType implements TypeInterface
|
||||
{
|
||||
return filter_var($value, FILTER_VALIDATE_INT) === false ? false : true;
|
||||
}
|
||||
|
||||
public function getFormatedValue($value)
|
||||
{
|
||||
return $this->isValid($value) ? $value : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,12 @@ class JsonType implements TypeInterface
|
||||
|
||||
public function isValid($value)
|
||||
{
|
||||
json_decode($value);
|
||||
json_decode($value, true);
|
||||
return (json_last_error() == JSON_ERROR_NONE);
|
||||
}
|
||||
|
||||
public function getFormatedValue($value)
|
||||
{
|
||||
return $this->isValid($value) ? json_decode($value, true) : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,4 +132,14 @@ class TypeCollection implements \Iterator
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getFormatedValue($value) {
|
||||
foreach($this as $type) {
|
||||
if($type->isValid($value)) {
|
||||
return $type->getFormatedValue($value);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,4 +33,6 @@ interface TypeInterface
|
||||
public function getType();
|
||||
|
||||
public function isValid($value);
|
||||
|
||||
public function getFormatedValue($value);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{include file='includes/header.inc.html'}
|
||||
|
||||
<div class="loginpage">
|
||||
|
||||
{{intl l='abcd'}|capitalize}
|
||||
<div class="brandbar container">
|
||||
<a class="brand" href="index.php">{images file='assets/img/logo-thelia-34px.png'}<img src="{$asset_url}" alt="{intl l='Thelia, solution e-commerce libre'}" />{/images}</a>
|
||||
</div>
|
||||
@@ -15,7 +15,7 @@
|
||||
<div class="hero-unit">
|
||||
<h1>{intl l='Thelia Back Office'}</h1>
|
||||
|
||||
<form action="/admin" method="post" class="well form-inline" {form_enctype form=$form}>
|
||||
<form action="admin/login" method="post" class="well form-inline" {form_enctype form=$form}>
|
||||
{form_field_hidden form=$form}
|
||||
{form_field form=$form.username}
|
||||
{form_error form=$form.username}
|
||||
@@ -27,7 +27,9 @@
|
||||
<input type="password" class="input" placeholder="{intl l='Password'}" name="{$name}" />
|
||||
{/form_field}
|
||||
|
||||
{form_field form=$form.remember_me}
|
||||
<label class="checkbox"> <input type="checkbox" name="remember" value="yes"> {intl l='Remember me'}</label>
|
||||
{/form_field}
|
||||
|
||||
<button type="submit" class="btn btn-primary">{intl l='Login'} <i class="icon-play"></i></button>
|
||||
</form>
|
||||
|
||||
29
templates/smarty-sample/category.html
Executable file
29
templates/smarty-sample/category.html
Executable file
@@ -0,0 +1,29 @@
|
||||
{*loop name="category0" type="category" parent="0"}
|
||||
<h2>CATEGORY : #TITLE</h2>
|
||||
{loop name="category1" type="category" parent="#ID"}
|
||||
<hr />
|
||||
<h3>SUBCATEGORY : #TITLE (#LOOP_COUNT / #LOOP_TOTAL)</h3>
|
||||
{loop name="product" type="product" category="#ID"}
|
||||
<h3>PRODUCT : #REF / #TITLE</h3>
|
||||
#PRICE €
|
||||
{/loop}
|
||||
<hr />
|
||||
<hr />
|
||||
{/loop}
|
||||
|
||||
{loop name="product" type="product" category="#ID"}
|
||||
<h3>PRODUCT : #REF / #TITLE</h3>
|
||||
#PRICE €
|
||||
{/loop}
|
||||
<hr />
|
||||
<hr />
|
||||
{/loop*}
|
||||
<h2>PRODUCTS</h2>
|
||||
{loop name="product" type="product" order="min_price"}
|
||||
<h3>PRODUCT : #REF / #TITLE</h3>
|
||||
price : #PRICE €<br />
|
||||
promo price : #PROMO_PRICE €<br />
|
||||
is promo : #PROMO<br />
|
||||
is new : #NEW<br />
|
||||
weight : #WEIGHT<br />
|
||||
{/loop}
|
||||
12
templates/smarty-sample/included.html
Normal file
12
templates/smarty-sample/included.html
Normal file
@@ -0,0 +1,12 @@
|
||||
{loop name="included0" type="category" parent="0"}
|
||||
<h2>Out before - CATEGORY : #TITLE (#LOOP_COUNT / #LOOP_TOTAL)</h2>
|
||||
{loop name="category1" type="category" parent="#ID"}
|
||||
<h3>Inner - SUBCATEGORY : #TITLE (#LOOP_COUNT / #LOOP_TOTAL)</h3>
|
||||
{/loop}
|
||||
|
||||
{loop name="category2" type="category" parent="#ID"}
|
||||
<h3>Inner 2 - SUBCATEGORY : #TITLE (#LOOP_COUNT / #LOOP_TOTAL)</h3>
|
||||
{/loop}
|
||||
<h2>Out after - CATEGORY : #TITLE (#LOOP_COUNT / #LOOP_TOTAL)</h2>
|
||||
<hr />
|
||||
{/loop}
|
||||
@@ -17,7 +17,7 @@ An image from asset directory :
|
||||
<p>Category loop example</p>
|
||||
<ul>
|
||||
{loop type="category" name="catloop1"}
|
||||
<li>{$__COUNT__}/{$__TOTAL__} : {$ID} {$TITLE}, children: {$NB_CHILD}
|
||||
<li>{$LOOP_COUNT}/{$LOOP_TOTAL} : {$ID} {$TITLE}, children: {$NB_CHILD}
|
||||
{ifloop rel="inner1"}
|
||||
<ul>
|
||||
{loop type="category" name="inner1" parent="{$ID}"}
|
||||
@@ -40,7 +40,7 @@ An image from asset directory :
|
||||
Hey ! Loop catloop2 is not empty:
|
||||
<ul>
|
||||
{loop type="category" name="catloop2" parent="12"}
|
||||
<li>{$__COUNT__}/{$__TOTAL__} : {$ID} {$TITLE}</li>
|
||||
<li>{$LOOP_COUNT}/{$LOOP_TOTAL} : {$ID} {$TITLE}</li>
|
||||
{/loop}
|
||||
</ul>
|
||||
{/ifloop}
|
||||
@@ -57,7 +57,7 @@ An image from asset directory :
|
||||
Loop catloop3 is not empty:
|
||||
<ul>
|
||||
{loop type="category" name="catloop3" parent="0"}
|
||||
<li>{$__COUNT__}/{$__TOTAL__} : {$ID} {$TITLE}</li>
|
||||
<li>{$LOOP_COUNT}/{$LOOP_TOTAL} : {$ID} {$TITLE}</li>
|
||||
{/loop}
|
||||
</ul>
|
||||
{/ifloop}
|
||||
@@ -86,20 +86,20 @@ An image from asset directory :
|
||||
<p>PAGE 1</p>
|
||||
<ul>
|
||||
{loop type="category" name="catloopwithpagination1" limit="2" page="1"}
|
||||
<li>{$__COUNT__}/{$__TOTAL__} : {$ID} {$TITLE}</li>
|
||||
<li>{$LOOP_COUNT}/{$LOOP_TOTAL} : {$ID} {$TITLE}</li>
|
||||
{/loop}
|
||||
</ul>
|
||||
<p>PAGE 2</p>
|
||||
<ul>
|
||||
{loop type="category" name="catloopwithpagination2" limit="2" page="2"}
|
||||
<li>{$__COUNT__}/{$__TOTAL__} : {$ID} {$TITLE}</li>
|
||||
<li>{$LOOP_COUNT}/{$LOOP_TOTAL} : {$ID} {$TITLE}</li>
|
||||
{/loop}
|
||||
</ul>
|
||||
<p>PAGE 1000</p>
|
||||
<ul>
|
||||
|
||||
{loop type="category" name="catloopwithpagination1000" limit="2" page="1000"}
|
||||
<li>{$__COUNT__}/{$__TOTAL__} : {$ID} {$TITLE}</li>
|
||||
<li>{$LOOP_COUNT}/{$LOOP_TOTAL} : {$ID} {$TITLE}</li>
|
||||
{/loop}
|
||||
|
||||
{elseloop rel="catloopwithpagination1000"}
|
||||
@@ -114,7 +114,7 @@ An image from asset directory :
|
||||
<p>PAGE {$current_page} :</p>
|
||||
<ul>
|
||||
{loop type="category" name="catloopwithpaginationchoice" limit="2" page="{$current_page}"}
|
||||
<li>{$__COUNT__}/{$__TOTAL__} : {$ID} {$TITLE}</li>
|
||||
<li>{$LOOP_COUNT}/{$LOOP_TOTAL} : {$ID} {$TITLE}</li>
|
||||
{/loop}
|
||||
</ul>
|
||||
<p>page choice</p>
|
||||
|
||||
Reference in New Issue
Block a user