Initial commit
This commit is contained in:
231
core/lib/Thelia/Tools/AddressFormat.php
Normal file
231
core/lib/Thelia/Tools/AddressFormat.php
Normal file
@@ -0,0 +1,231 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
|
||||
namespace Thelia\Tools;
|
||||
|
||||
use CommerceGuys\Addressing\Formatter\DefaultFormatter;
|
||||
use CommerceGuys\Addressing\Formatter\PostalLabelFormatter;
|
||||
use CommerceGuys\Addressing\Model\Address;
|
||||
use CommerceGuys\Addressing\Model\AddressInterface;
|
||||
use CommerceGuys\Addressing\Repository\AddressFormatRepository;
|
||||
use CommerceGuys\Addressing\Repository\CountryRepository;
|
||||
use CommerceGuys\Addressing\Repository\SubdivisionRepository;
|
||||
use Thelia\Model\Country;
|
||||
use Thelia\Model\CountryQuery;
|
||||
use Thelia\Model\Lang;
|
||||
use Thelia\Model\OrderAddress;
|
||||
|
||||
/**
|
||||
* Class AddressFormat
|
||||
* @package Thelia\Tools
|
||||
* @author Julien Chanséaume <julien@thelia.net>
|
||||
*/
|
||||
class AddressFormat
|
||||
{
|
||||
private static $instance;
|
||||
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
if (!isset(self::$instance)) {
|
||||
self::$instance = new AddressFormat();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Format an address
|
||||
*
|
||||
* @param AddressInterface $address
|
||||
* @param null $locale
|
||||
* @param bool $html
|
||||
* @param string $htmlTag
|
||||
* @param array $htmlAttributes
|
||||
* @return string
|
||||
*/
|
||||
public function format(
|
||||
AddressInterface $address,
|
||||
$locale = null,
|
||||
$html = true,
|
||||
$htmlTag = "p",
|
||||
$htmlAttributes = []
|
||||
) {
|
||||
$locale = $this->normalizeLocale($locale);
|
||||
|
||||
$addressFormatRepository = new AddressFormatRepository();
|
||||
$countryRepository = new CountryRepository();
|
||||
$subdivisionRepository = new SubdivisionRepository();
|
||||
|
||||
$formatter = new DefaultFormatter(
|
||||
$addressFormatRepository,
|
||||
$countryRepository,
|
||||
$subdivisionRepository,
|
||||
$locale
|
||||
);
|
||||
|
||||
$formatter->setOption('html', $html);
|
||||
$formatter->setOption('html_tag', $htmlTag);
|
||||
$formatter->setOption('html_attributes', $htmlAttributes);
|
||||
|
||||
|
||||
$addressFormatted = $formatter->format($address);
|
||||
|
||||
return $addressFormatted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a Thelia address (Address or OrderAddress)
|
||||
*
|
||||
* @param \Thelia\Model\OrderAddress|OrderAddress $address
|
||||
* @param null $locale
|
||||
* @param bool $html
|
||||
* @param string $htmlTag
|
||||
* @param array $htmlAttributes
|
||||
* @return string
|
||||
*/
|
||||
public function formatTheliaAddress($address, $locale = null, $html = true, $htmlTag = "p", $htmlAttributes = [])
|
||||
{
|
||||
$address = $this->mapTheliaAddress($address, $locale);
|
||||
return $this->format($address, $locale, $html, $htmlTag, $htmlAttributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format an address to a postal label
|
||||
*
|
||||
* @param AddressInterface $address
|
||||
* @param null $locale
|
||||
* @param null $originCountry
|
||||
* @param array $options
|
||||
* @return string
|
||||
*/
|
||||
public function postalLabelFormat(AddressInterface $address, $locale = null, $originCountry = null, $options = [])
|
||||
{
|
||||
$locale = $this->normalizeLocale($locale);
|
||||
|
||||
$addressFormatRepository = new AddressFormatRepository();
|
||||
$countryRepository = new CountryRepository();
|
||||
$subdivisionRepository = new SubdivisionRepository();
|
||||
|
||||
if (null === $originCountry) {
|
||||
$countryId = Country::getShopLocation();
|
||||
if (null === $country = CountryQuery::create()->findPk($countryId)) {
|
||||
$country = Country::getDefaultCountry();
|
||||
}
|
||||
|
||||
$originCountry = $country->getIsoalpha2();
|
||||
}
|
||||
|
||||
$formatter = new PostalLabelFormatter(
|
||||
$addressFormatRepository,
|
||||
$countryRepository,
|
||||
$subdivisionRepository,
|
||||
$originCountry,
|
||||
$locale,
|
||||
$options
|
||||
);
|
||||
|
||||
$addressFormatted = $formatter->format($address);
|
||||
|
||||
return $addressFormatted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a Thelia address (Address or OrderAddress) to a postal label
|
||||
*
|
||||
* @param \Thelia\Model\OrderAddress|OrderAddress $address
|
||||
* @param null $locale
|
||||
* @param null $originCountry
|
||||
* @param array $options
|
||||
* @return string
|
||||
*/
|
||||
public function postalLabelFormatTheliaAddress($address, $locale = null, $originCountry = null, $options = [])
|
||||
{
|
||||
$address = $this->mapTheliaAddress($address, $locale);
|
||||
return $this->postalLabelFormat($address, $locale, $originCountry, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a Thelia address (Address or OrderAddress) to ImmutableAddressInterface
|
||||
*
|
||||
* @param \Thelia\Model\OrderAddress|OrderAddress $address
|
||||
* @return Address|\CommerceGuys\Addressing\Model\ImmutableAddressInterface
|
||||
*/
|
||||
protected function mapTheliaAddress($address, $locale = null)
|
||||
{
|
||||
$country = $address->getCountry();
|
||||
if (null === $locale) {
|
||||
$locale = Lang::getDefaultLanguage()->getLocale();
|
||||
}
|
||||
$customerTitle = $address->getCustomerTitle()
|
||||
->setLocale($this->denormalizeLocale($locale))
|
||||
->getShort()
|
||||
;
|
||||
|
||||
$addressModel = new Address();
|
||||
$addressModel = $addressModel
|
||||
->withCountryCode($country->getIsoalpha2())
|
||||
->withAddressLine1($address->getAddress1())
|
||||
->withAddressLine2($address->getAddress2())
|
||||
->withPostalCode($address->getZipcode())
|
||||
->withLocality($address->getCity())
|
||||
->withOrganization($address->getCompany())
|
||||
->withRecipient(
|
||||
sprintf(
|
||||
'%s %s %s',
|
||||
$customerTitle,
|
||||
$address->getLastname(),
|
||||
$address->getFirstname()
|
||||
)
|
||||
)
|
||||
;
|
||||
|
||||
|
||||
if ($country->getHasStates() && intval($address->getStateId()) !== 0) {
|
||||
$addressModel = $addressModel->withAdministrativeArea(
|
||||
sprintf(
|
||||
'%s-%s',
|
||||
$country->getIsoalpha2(),
|
||||
$address->getState()->getIsocode()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return $addressModel;
|
||||
}
|
||||
|
||||
private function normalizeLocale($locale)
|
||||
{
|
||||
if (null !== $locale) {
|
||||
$locale = str_replace('_', '-', $locale);
|
||||
}
|
||||
|
||||
return $locale;
|
||||
}
|
||||
|
||||
private function denormalizeLocale($locale)
|
||||
{
|
||||
if (null !== $locale) {
|
||||
$locale = str_replace('-', '_', $locale);
|
||||
}
|
||||
|
||||
return $locale;
|
||||
}
|
||||
}
|
||||
54
core/lib/Thelia/Tools/DateTimeFormat.php
Normal file
54
core/lib/Thelia/Tools/DateTimeFormat.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace Thelia\Tools;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class DateTimeFormat
|
||||
{
|
||||
protected $request;
|
||||
|
||||
public function __construct(Request $request)
|
||||
{
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
public static function getInstance(Request $request)
|
||||
{
|
||||
return new DateTimeFormat($request);
|
||||
}
|
||||
|
||||
public function getFormat($output = null)
|
||||
{
|
||||
$lang = $this->request->getSession()->getLang();
|
||||
|
||||
$format = null;
|
||||
|
||||
if ($lang) {
|
||||
switch ($output) {
|
||||
case "date":
|
||||
$format = $lang->getDateFormat();
|
||||
break;
|
||||
case "time":
|
||||
$format = $lang->getTimeFormat();
|
||||
break;
|
||||
default:
|
||||
case "datetime":
|
||||
$format = $lang->getDateTimeFormat();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $format;
|
||||
}
|
||||
}
|
||||
145
core/lib/Thelia/Tools/FileDownload/FileDownloader.php
Normal file
145
core/lib/Thelia/Tools/FileDownload/FileDownloader.php
Normal file
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace Thelia\Tools\FileDownload;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Translation\Translator;
|
||||
use Thelia\Core\Translation\Translator as TheliaTranslator;
|
||||
use Thelia\Exception\FileNotFoundException;
|
||||
use Thelia\Exception\HttpUrlException;
|
||||
use Thelia\Log\Tlog;
|
||||
use Thelia\Tools\URL;
|
||||
|
||||
/**
|
||||
* Class FileDownloader
|
||||
* @package Thelia\Tools\FileDownload
|
||||
* @author Benjamin Perche <bperche@openstudio.fr>
|
||||
*/
|
||||
class FileDownloader implements FileDownloaderInterface
|
||||
{
|
||||
/** @var LoggerInterface */
|
||||
protected $logger;
|
||||
|
||||
/** @var Translator */
|
||||
protected $translator;
|
||||
|
||||
public function __construct(LoggerInterface $logger, Translator $translator)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
|
||||
$this->translator = $translator;
|
||||
}
|
||||
|
||||
public static function getInstance()
|
||||
{
|
||||
return new static(Tlog::getInstance(), TheliaTranslator::getInstance());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @param string $pathToStore
|
||||
* @throws \Thelia\Exception\FileNotFoundException
|
||||
* @throws \ErrorException
|
||||
* @throws \HttpUrlException
|
||||
*
|
||||
* Downloads the file $url in $pathToStore
|
||||
*/
|
||||
public function download($url, $pathToStore)
|
||||
{
|
||||
if (!URL::checkUrl($url)) {
|
||||
/**
|
||||
* The URL is not valid
|
||||
*/
|
||||
throw new HttpUrlException(
|
||||
$this->translator->trans(
|
||||
"Tried to download a file, but the URL was not valid: %url",
|
||||
[
|
||||
"%url" => $url
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to get the file if it is online
|
||||
*/
|
||||
$con = curl_init($url);
|
||||
curl_setopt($con, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($con, CURLOPT_FOLLOWLOCATION, true);
|
||||
|
||||
$response = curl_exec($con);
|
||||
$errno = curl_errno($con);
|
||||
$curlErrorMessage = curl_error($con);
|
||||
|
||||
$httpCode = curl_getinfo($con, CURLINFO_HTTP_CODE);
|
||||
|
||||
curl_close($con);
|
||||
|
||||
if (false === $response || $errno !== 0 ||
|
||||
($httpCode != "200" && $httpCode != "204")
|
||||
) {
|
||||
/**
|
||||
* The server is down ? The file doesn't exist ? Anything else ?
|
||||
*/
|
||||
$errorMessage = $this->translator->trans(
|
||||
"cURL errno %errno, http code %http_code on link \"%path\": %error",
|
||||
[
|
||||
"%errno" => $errno,
|
||||
"%path" => $url,
|
||||
"%error" => $curlErrorMessage,
|
||||
"%http_code" => $httpCode,
|
||||
]
|
||||
);
|
||||
|
||||
$this->logger
|
||||
->error($errorMessage)
|
||||
;
|
||||
|
||||
throw new FileNotFoundException($errorMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inform that you've downloaded a file
|
||||
*/
|
||||
$this->logger
|
||||
->info(
|
||||
$this->translator->trans(
|
||||
"The file %path has been successfully downloaded",
|
||||
[
|
||||
"%path" => $url
|
||||
]
|
||||
)
|
||||
)
|
||||
;
|
||||
|
||||
/**
|
||||
* Then try to write it on the disk
|
||||
*/
|
||||
$file = @fopen($pathToStore, "w");
|
||||
|
||||
if ($file === false) {
|
||||
$translatedErrorMessage = $this->translator->trans(
|
||||
"Failed to open a writing stream on the file: %file",
|
||||
[
|
||||
"%file" => $pathToStore
|
||||
]
|
||||
);
|
||||
|
||||
$this->logger->error($translatedErrorMessage);
|
||||
throw new \ErrorException($translatedErrorMessage);
|
||||
}
|
||||
|
||||
fputs($file, $response);
|
||||
fclose($file);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace Thelia\Tools\FileDownload;
|
||||
|
||||
/**
|
||||
* Trait FileDownloaderAwareTrait
|
||||
* @package Thelia\Tools\FileDownload
|
||||
* @author Benjamin Perche <bperche@openstudio.fr>
|
||||
*/
|
||||
trait FileDownloaderAwareTrait
|
||||
{
|
||||
/** @var FileDownloaderInterface */
|
||||
protected $fileDownloader;
|
||||
|
||||
/**
|
||||
* @return FileDownloaderInterface
|
||||
*/
|
||||
public function getFileDownloader()
|
||||
{
|
||||
if (!$this->fileDownloader instanceof FileDownloaderInterface) {
|
||||
$this->fileDownloader = FileDownloader::getInstance();
|
||||
}
|
||||
|
||||
return $this->fileDownloader;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FileDownloaderInterface $fileDownloader
|
||||
* @return $this
|
||||
*/
|
||||
public function setFileDownloader(FileDownloaderInterface $fileDownloader)
|
||||
{
|
||||
$this->fileDownloader = $fileDownloader;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
namespace Thelia\Tools\FileDownload;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Translation\Translator;
|
||||
|
||||
/**
|
||||
* Class FileDownloader
|
||||
* @package Thelia\Tools\FileDownload
|
||||
* @author Benjamin Perche <bperche@openstudio.fr>
|
||||
*/
|
||||
interface FileDownloaderInterface
|
||||
{
|
||||
/**
|
||||
* @param string $url
|
||||
* @param string $pathToStore
|
||||
* @throws \Thelia\Exception\FileNotFoundException
|
||||
* @throws \ErrorException
|
||||
* @throws \HttpUrlException
|
||||
*
|
||||
* Downloads the file $url in $pathToStore
|
||||
*/
|
||||
public function download($url, $pathToStore);
|
||||
|
||||
public function __construct(LoggerInterface $logger, Translator $translator);
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*
|
||||
* Returns an hydrated instance
|
||||
*/
|
||||
public static function getInstance();
|
||||
}
|
||||
142
core/lib/Thelia/Tools/I18n.php
Normal file
142
core/lib/Thelia/Tools/I18n.php
Normal file
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace Thelia\Tools;
|
||||
|
||||
use Propel\Runtime\ActiveQuery\ModelCriteria;
|
||||
use Thelia\Model\Lang;
|
||||
|
||||
/**
|
||||
* Created by JetBrains PhpStorm.
|
||||
* Date: 8/19/13
|
||||
* Time: 3:24 PM
|
||||
*
|
||||
* Helper for translations
|
||||
*
|
||||
* @package I18n
|
||||
* @author Guillaume MOREL <gmorel@openstudio.fr>
|
||||
*
|
||||
*/
|
||||
class I18n
|
||||
{
|
||||
protected static $defaultLocale;
|
||||
|
||||
/**
|
||||
* Create a \DateTime from a date picker form input
|
||||
* The date format is the same as the one from the current User Session
|
||||
* Ex : $lang = $session->getLang()
|
||||
*
|
||||
* @param Lang $lang Object containing date format
|
||||
* @param string $date String to convert
|
||||
*
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getDateTimeFromForm(Lang $lang, $date)
|
||||
{
|
||||
$currentDateFormat = $lang->getDateFormat();
|
||||
|
||||
return \DateTime::createFromFormat($currentDateFormat, $date);
|
||||
}
|
||||
|
||||
public static function forceI18nRetrieving($askedLocale, $modelName, $id, $needed = array('Title'))
|
||||
{
|
||||
$i18nQueryClass = sprintf("\\Thelia\\Model\\%sI18nQuery", $modelName);
|
||||
$i18nClass = sprintf("\\Thelia\\Model\\%sI18n", $modelName);
|
||||
|
||||
/* get customer language translation */
|
||||
$i18n = $i18nQueryClass::create()
|
||||
->filterById($id)
|
||||
->filterByLocale(
|
||||
$askedLocale
|
||||
)->findOne();
|
||||
/* or default translation */
|
||||
if (null === $i18n) {
|
||||
$i18n = $i18nQueryClass::create()
|
||||
->filterById($id)
|
||||
->filterByLocale(
|
||||
Lang::getDefaultLanguage()->getLocale()
|
||||
)->findOne();
|
||||
}
|
||||
if (null === $i18n) {
|
||||
// @todo something else ?
|
||||
$i18n = new $i18nClass();
|
||||
;
|
||||
$i18n->setId($id);
|
||||
foreach ($needed as $need) {
|
||||
$method = sprintf('set%s', $need);
|
||||
if (method_exists($i18n, $method)) {
|
||||
$i18n->$method('DEFAULT ' . strtoupper($need));
|
||||
} else {
|
||||
// @todo throw sg ?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $i18n;
|
||||
}
|
||||
|
||||
public static function addI18nCondition(
|
||||
ModelCriteria $query,
|
||||
$i18nTableName,
|
||||
$tableIdColumn,
|
||||
$i18nIdColumn,
|
||||
$localeColumn,
|
||||
$locale
|
||||
) {
|
||||
if (null === static::$defaultLocale) {
|
||||
static::$defaultLocale = Lang::getDefaultLanguage()->getLocale();
|
||||
}
|
||||
|
||||
$locale = static::realEscape($locale);
|
||||
$defaultLocale = static::realEscape(static::$defaultLocale);
|
||||
|
||||
$query
|
||||
->_and()
|
||||
->where(
|
||||
"CASE WHEN ".$tableIdColumn." IN".
|
||||
"(SELECT DISTINCT ".$i18nIdColumn." ".
|
||||
"FROM `".$i18nTableName."` ".
|
||||
"WHERE locale=$locale) ".
|
||||
"THEN ".$localeColumn." = $locale ".
|
||||
"ELSE ".$localeColumn." = $defaultLocale ".
|
||||
"END"
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $str
|
||||
* @return string
|
||||
*
|
||||
* Really escapes a string for SQL query.
|
||||
*/
|
||||
public static function realEscape($str)
|
||||
{
|
||||
$str = trim($str, "\"'");
|
||||
|
||||
$return = "CONCAT(";
|
||||
$len = strlen($str);
|
||||
|
||||
for ($i = 0; $i < $len; ++$i) {
|
||||
$return .= "CHAR(".ord($str[$i])."),";
|
||||
}
|
||||
|
||||
if ($i > 0) {
|
||||
$return = substr($return, 0, -1);
|
||||
} else {
|
||||
$return = "\"\"";
|
||||
}
|
||||
$return .= ")";
|
||||
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
32
core/lib/Thelia/Tools/Image.php
Normal file
32
core/lib/Thelia/Tools/Image.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace Thelia\Tools;
|
||||
|
||||
class Image
|
||||
{
|
||||
public static function isImage($filePath, $allowedImageTypes = null)
|
||||
{
|
||||
$imageFile = getimagesize($filePath);
|
||||
$imageType = $imageFile[2];
|
||||
|
||||
if (!is_array($allowedImageTypes) && $imageType != IMAGETYPE_UNKNOWN) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (in_array($imageType, $allowedImageTypes)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
84
core/lib/Thelia/Tools/MoneyFormat.php
Normal file
84
core/lib/Thelia/Tools/MoneyFormat.php
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace Thelia\Tools;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Thelia\Model\CurrencyQuery;
|
||||
|
||||
class MoneyFormat extends NumberFormat
|
||||
{
|
||||
public static function getInstance(Request $request)
|
||||
{
|
||||
return new MoneyFormat($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a standard number, with '.' as decimal point no thousands separator, and no currency symbol
|
||||
* so that this number can be used to perform calculations.
|
||||
*
|
||||
* @param float $number the number
|
||||
* @param string $decimals number of decimal figures
|
||||
* @return string
|
||||
*/
|
||||
public function formatStandardMoney($number, $decimals = null)
|
||||
{
|
||||
return parent::formatStandardNumber($number, $decimals);
|
||||
}
|
||||
|
||||
public function format(
|
||||
$number,
|
||||
$decimals = null,
|
||||
$decPoint = null,
|
||||
$thousandsSep = null,
|
||||
$symbol = null
|
||||
) {
|
||||
$number = parent::format($number, $decimals, $decPoint, $thousandsSep);
|
||||
|
||||
if ($symbol !== null) {
|
||||
return $number . ' ' . $symbol;
|
||||
}
|
||||
|
||||
return $number;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.3
|
||||
* @param float $number
|
||||
* @param int $decimals
|
||||
* @param string $decPoint
|
||||
* @param string $thousandsSep
|
||||
* @param int|null $currencyId
|
||||
* @return string
|
||||
*/
|
||||
public function formatByCurrency(
|
||||
$number,
|
||||
$decimals = null,
|
||||
$decPoint = null,
|
||||
$thousandsSep = null,
|
||||
$currencyId = null
|
||||
) {
|
||||
$number = parent::format($number, $decimals, $decPoint, $thousandsSep);
|
||||
|
||||
$currency = $currencyId !== null ? CurrencyQuery::create()->findPk($currencyId) : $this->request->getSession()->getCurrency();
|
||||
|
||||
if ($currency !== null && strpos($currency->getFormat(), '%n') !== false) {
|
||||
return str_replace(
|
||||
['%n', '%s', '%c'],
|
||||
[$number, $currency->getSymbol(), $currency->getCode()],
|
||||
$currency->getFormat()
|
||||
);
|
||||
}
|
||||
|
||||
return $number;
|
||||
}
|
||||
}
|
||||
65
core/lib/Thelia/Tools/NumberFormat.php
Normal file
65
core/lib/Thelia/Tools/NumberFormat.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace Thelia\Tools;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class NumberFormat
|
||||
{
|
||||
protected $request;
|
||||
|
||||
public function __construct(Request $request)
|
||||
{
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
public static function getInstance(Request $request)
|
||||
{
|
||||
return new NumberFormat($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a standard number, with '.' as decimal point and no thousands separator
|
||||
* so that this number can be used to perform calculations.
|
||||
*
|
||||
* @param float $number the number
|
||||
* @param string $decimals number of decimal figures
|
||||
* @return string
|
||||
*/
|
||||
public function formatStandardNumber($number, $decimals = null)
|
||||
{
|
||||
$lang = $this->request->getSession()->getLang();
|
||||
|
||||
if ($decimals === null) {
|
||||
$decimals = $lang->getDecimals();
|
||||
}
|
||||
|
||||
return number_format($number, $decimals, '.', '');
|
||||
}
|
||||
|
||||
public function format($number, $decimals = null, $decPoint = null, $thousandsSep = null)
|
||||
{
|
||||
$lang = $this->request->getSession()->getLang();
|
||||
|
||||
if ($decimals === null) {
|
||||
$decimals = $lang->getDecimals();
|
||||
}
|
||||
if ($decPoint === null) {
|
||||
$decPoint = $lang->getDecimalSeparator();
|
||||
}
|
||||
if ($thousandsSep === null) {
|
||||
$thousandsSep = $lang->getThousandsSeparator();
|
||||
}
|
||||
return number_format($number, $decimals, $decPoint, $thousandsSep);
|
||||
}
|
||||
}
|
||||
54
core/lib/Thelia/Tools/Password.php
Normal file
54
core/lib/Thelia/Tools/Password.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace Thelia\Tools;
|
||||
|
||||
/**
|
||||
* Class Password
|
||||
* @package Thelia\Tools
|
||||
* @author Manuel Raynaud <manu@raynaud.io>
|
||||
*/
|
||||
class Password
|
||||
{
|
||||
private static function randgen($letter, $length)
|
||||
{
|
||||
$string = "";
|
||||
do {
|
||||
$string .= substr(str_shuffle($letter), 0, 1);
|
||||
} while (strlen($string) < $length);
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* generate a Random password with defined length
|
||||
*
|
||||
* @param int $length
|
||||
* @return mixed
|
||||
*/
|
||||
public static function generateRandom($length = 8)
|
||||
{
|
||||
$letter = "abcdefghijklmnopqrstuvwxyz";
|
||||
$letter .= "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
$letter .= "0123456789";
|
||||
|
||||
return self::randgen($letter, $length);
|
||||
}
|
||||
|
||||
public static function generateHexaRandom($length = 8)
|
||||
{
|
||||
$letter = "ABCDEF";
|
||||
$letter .= "0123456789";
|
||||
|
||||
return self::randgen($letter, $length);
|
||||
}
|
||||
}
|
||||
62
core/lib/Thelia/Tools/RememberMeTrait.php
Normal file
62
core/lib/Thelia/Tools/RememberMeTrait.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
|
||||
namespace Thelia\Tools;
|
||||
|
||||
use Thelia\Core\HttpFoundation\Request;
|
||||
use Thelia\Core\Security\Token\CookieTokenProvider;
|
||||
use Thelia\Core\Security\User\UserInterface;
|
||||
|
||||
/**
|
||||
* Trait RememberMeTrait
|
||||
* @package Thelia\Tools
|
||||
* @author Julien Chanséaume <jchanseaume@openstudio.fr>
|
||||
*/
|
||||
trait RememberMeTrait
|
||||
{
|
||||
/**
|
||||
* Get the remember me key from the cookie.
|
||||
*
|
||||
* @return string hte key found, or null if no key was found.
|
||||
*/
|
||||
protected function getRememberMeKeyFromCookie(Request $request, $cookieName)
|
||||
{
|
||||
$ctp = new CookieTokenProvider();
|
||||
|
||||
return $ctp->getKeyFromCookie($request, $cookieName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the remember me cookie for the given user.
|
||||
*/
|
||||
protected function createRememberMeCookie(UserInterface $user, $cookieName, $cookieExpiration)
|
||||
{
|
||||
$ctp = new CookieTokenProvider();
|
||||
|
||||
$ctp->createCookie(
|
||||
$user,
|
||||
$cookieName,
|
||||
$cookieExpiration
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the remember me cookie.
|
||||
*/
|
||||
protected function clearRememberMeCookie($cookieName)
|
||||
{
|
||||
$ctp = new CookieTokenProvider();
|
||||
|
||||
$ctp->clearCookie($cookieName);
|
||||
}
|
||||
}
|
||||
97
core/lib/Thelia/Tools/Rest/ResponseRest.php
Normal file
97
core/lib/Thelia/Tools/Rest/ResponseRest.php
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
namespace Thelia\Tools\Rest;
|
||||
|
||||
use Thelia\Core\HttpFoundation\Response;
|
||||
use Symfony\Component\Serializer\Serializer;
|
||||
use Symfony\Component\Serializer\Encoder\XmlEncoder;
|
||||
use Symfony\Component\Serializer\Encoder\JsonEncoder;
|
||||
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;
|
||||
|
||||
/**
|
||||
* Class ResponseRest Create a serialized Response
|
||||
*
|
||||
* @package Thelia\Tools\Rest
|
||||
*/
|
||||
class ResponseRest extends Response
|
||||
{
|
||||
/** @var Response Response Object */
|
||||
protected $response;
|
||||
|
||||
/** @var string Response format */
|
||||
protected $format;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $data Array to be serialized
|
||||
* @param string $format serialization format, text, xml or json available
|
||||
* @param integer $status The response status code
|
||||
* @param array $headers An array of response headers
|
||||
*
|
||||
* @throws \InvalidArgumentException When the HTTP status code is not valid
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function __construct($data = null, $format = 'json', $status = 200, $headers = array())
|
||||
{
|
||||
parent::__construct('', $status, $headers);
|
||||
|
||||
if ($format == 'text') {
|
||||
if (isset($data)) {
|
||||
$this->setContent($data);
|
||||
}
|
||||
|
||||
$this->headers->set('Content-Type', 'text/plain');
|
||||
} else {
|
||||
$this->format = $format;
|
||||
$serializer = $this->getSerializer();
|
||||
|
||||
if (isset($data)) {
|
||||
$this->setContent($serializer->serialize($data, $this->format));
|
||||
}
|
||||
|
||||
$this->headers->set('Content-Type', 'application/' . $this->format);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Content to be serialized in the response, array or object
|
||||
*
|
||||
* @param array $data array or object to be serialized
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setRestContent($data)
|
||||
{
|
||||
$serializer = $this->getSerializer();
|
||||
|
||||
if (isset($data)) {
|
||||
$this->setContent($serializer->serialize($data, $this->format));
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Serializer
|
||||
*
|
||||
* @return Serializer
|
||||
*/
|
||||
protected function getSerializer()
|
||||
{
|
||||
$encoders = array(new XmlEncoder(), new JsonEncoder());
|
||||
$normalizers = array(new GetSetMethodNormalizer());
|
||||
|
||||
return new Serializer($normalizers, $encoders);
|
||||
}
|
||||
}
|
||||
156
core/lib/Thelia/Tools/TokenProvider.php
Normal file
156
core/lib/Thelia/Tools/TokenProvider.php
Normal file
@@ -0,0 +1,156 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace Thelia\Tools;
|
||||
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
||||
use Symfony\Component\Translation\TranslatorInterface;
|
||||
use Thelia\Core\Security\Exception\TokenAuthenticationException;
|
||||
|
||||
/**
|
||||
* Class TokenProvider
|
||||
* @package Thelia\Tools
|
||||
* @author Benjamin Perche <bperche@openstudio.fr>
|
||||
*/
|
||||
class TokenProvider
|
||||
{
|
||||
/**
|
||||
* @var string The stored token for this page
|
||||
*/
|
||||
protected $token;
|
||||
|
||||
/**
|
||||
* @var SessionInterface The session where the token is stored
|
||||
*/
|
||||
protected $session;
|
||||
|
||||
/**
|
||||
* @var RequestStack
|
||||
*/
|
||||
protected $requestStack;
|
||||
|
||||
/**
|
||||
* @var TranslatorInterface The translator
|
||||
*/
|
||||
protected $translator;
|
||||
|
||||
/**
|
||||
* @var string the current name of the token
|
||||
*/
|
||||
protected $tokenName;
|
||||
|
||||
/**
|
||||
* @param RequestStack $requestStack
|
||||
* @param TranslatorInterface $translator
|
||||
* @param $tokenName
|
||||
*/
|
||||
public function __construct(RequestStack $requestStack, TranslatorInterface $translator, $tokenName)
|
||||
{
|
||||
/**
|
||||
* Store the services
|
||||
*/
|
||||
$this->requestStack = $requestStack;
|
||||
$this->session = $this->requestStack->getCurrentRequest()->getSession();
|
||||
$this->translator = $translator;
|
||||
$this->tokenName = $tokenName;
|
||||
|
||||
$this->token = $this->session->get($this->tokenName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function assignToken()
|
||||
{
|
||||
if (null === $this->token) {
|
||||
$this->token = $this->getToken();
|
||||
|
||||
$this->session->set($this->tokenName, $this->token);
|
||||
}
|
||||
|
||||
return $this->token;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $entryValue
|
||||
* @return bool
|
||||
* @throws \Thelia\Core\Security\Exception\TokenAuthenticationException
|
||||
*/
|
||||
public function checkToken($entryValue)
|
||||
{
|
||||
if (null === $this->token) {
|
||||
throw new TokenAuthenticationException(
|
||||
"Tried to check a token without assigning it before"
|
||||
);
|
||||
} elseif ($this->token !== $entryValue) {
|
||||
throw new TokenAuthenticationException(
|
||||
"Tried to validate an invalid token"
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function refreshToken()
|
||||
{
|
||||
$this->token = null;
|
||||
$this->assignToken();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getToken()
|
||||
{
|
||||
return self::generateToken();
|
||||
}
|
||||
|
||||
/**
|
||||
* Same method as getToken but can be called statically
|
||||
*
|
||||
* @alias getToken
|
||||
* @return string
|
||||
*/
|
||||
public static function generateToken()
|
||||
{
|
||||
$raw = self::getOpenSSLRandom();
|
||||
if (false === $raw) {
|
||||
$raw = self::getComplexRandom();
|
||||
}
|
||||
return md5($raw);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $length
|
||||
* @return string
|
||||
*/
|
||||
protected static function getOpenSSLRandom($length = 40)
|
||||
{
|
||||
if (!function_exists("openssl_random_pseudo_bytes")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return openssl_random_pseudo_bytes($length);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected static function getComplexRandom()
|
||||
{
|
||||
$firstValue = (float) (mt_rand(1, 0xFFFF) * rand(1, 0x10001));
|
||||
$secondValues = (float) (rand(1, 0xFFFF) * mt_rand(1, 0x10001));
|
||||
|
||||
return microtime() . ceil($firstValue / $secondValues) . uniqid();
|
||||
}
|
||||
}
|
||||
355
core/lib/Thelia/Tools/URL.php
Normal file
355
core/lib/Thelia/Tools/URL.php
Normal file
@@ -0,0 +1,355 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace Thelia\Tools;
|
||||
|
||||
use Symfony\Component\Routing\RequestContext;
|
||||
use Symfony\Component\Validator\Constraints\UrlValidator;
|
||||
use Thelia\Model\ConfigQuery;
|
||||
use Thelia\Model\LangQuery;
|
||||
use Thelia\Rewriting\RewritingResolver;
|
||||
use Thelia\Rewriting\RewritingRetriever;
|
||||
use Thelia\Core\HttpFoundation\Request;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
class URL
|
||||
{
|
||||
/** @var RewritingResolver $resolver */
|
||||
protected $resolver = null;
|
||||
|
||||
/** @var RewritingRetriever $retriever */
|
||||
protected $retriever = null;
|
||||
|
||||
/** @var RequestContext $requestContext */
|
||||
protected $requestContext;
|
||||
|
||||
const PATH_TO_FILE = true;
|
||||
const WITH_INDEX_PAGE = false;
|
||||
|
||||
protected static $instance = null;
|
||||
|
||||
/** @var string $baseUrlScheme a cache for the base URL scheme */
|
||||
private $baseUrlScheme = null;
|
||||
|
||||
public function __construct(ContainerInterface $container = null)
|
||||
{
|
||||
// Allow singleton style calls once instantiated.
|
||||
// For this to work, the URL service has to be instantiated very early. This is done manually
|
||||
// in TheliaHttpKernel, by calling $this->container->get('thelia.url.manager');
|
||||
self::$instance = $this;
|
||||
|
||||
if ($container !== null) {
|
||||
$this->requestContext = $container->get('router.admin')->getContext();
|
||||
}
|
||||
|
||||
$this->retriever = new RewritingRetriever();
|
||||
$this->resolver = new RewritingResolver();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RequestContext $requestContext
|
||||
* @since Version 2.2
|
||||
*/
|
||||
public function setRequestContext(RequestContext $requestContext)
|
||||
{
|
||||
$this->requestContext = $requestContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return this class instance, only once instanciated.
|
||||
*
|
||||
* @throws \RuntimeException if the class has not been instanciated.
|
||||
* @return \Thelia\Tools\URL the instance.
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
if (self::$instance == null) {
|
||||
throw new \RuntimeException("URL instance is not initialized.");
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the base URL, either the base_url defined in Config, or the URL
|
||||
* of the current language, if 'one_domain_foreach_lang' is enabled.
|
||||
*
|
||||
* @param bool $scheme_only if true, only the scheme will be returned. If false, the complete base URL, including path, is returned.
|
||||
*
|
||||
* @return string the base URL, with a trailing '/'
|
||||
*/
|
||||
public function getBaseUrl($scheme_only = false)
|
||||
{
|
||||
if (null === $this->baseUrlScheme) {
|
||||
$scheme = "http";
|
||||
$port = 80;
|
||||
|
||||
if ($host = $this->requestContext->getHost()) {
|
||||
$scheme = $this->requestContext->getScheme();
|
||||
|
||||
$port = '';
|
||||
|
||||
if ('http' === $scheme && 80 != $this->requestContext->getHttpPort()) {
|
||||
$port = ':'.$this->requestContext->getHttpPort();
|
||||
} elseif ('https' === $scheme && 443 != $this->requestContext->getHttpsPort()) {
|
||||
$port = ':'.$this->requestContext->getHttpsPort();
|
||||
}
|
||||
}
|
||||
|
||||
$this->baseUrlScheme = "$scheme://$host"."$port";
|
||||
}
|
||||
|
||||
return $scheme_only ? $this->baseUrlScheme : $this->baseUrlScheme . $this->requestContext->getBaseUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string the index page, which is in fact the base URL.
|
||||
*/
|
||||
public function getIndexPage()
|
||||
{
|
||||
// The index page is the base URL :)
|
||||
return $this->getBaseUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Absolute URL for a given path relative to web root. By default,
|
||||
* the script name (index_dev.php) is added to the URL in dev_environment, use
|
||||
* $path_only = true to get a path without the index script.
|
||||
*
|
||||
* @param string $path the relative path
|
||||
* @param array $parameters An array of parameters
|
||||
* @param boolean $path_only if true (PATH_TO_FILE), getIndexPage() will not be added
|
||||
*
|
||||
* @return string The generated URL
|
||||
*/
|
||||
public function absoluteUrl($path, array $parameters = null, $path_only = self::WITH_INDEX_PAGE)
|
||||
{
|
||||
// Already absolute ?
|
||||
if (substr($path, 0, 4) != 'http') {
|
||||
// Prevent duplication of the subdirectory name when Thelia is installed in a subdirectory.
|
||||
// This happens when $path was calculated with Router::generate(), which returns an absolute URL,
|
||||
// starting at web server root. For example, if Thelia is installed in /thelia2, we got something like /thelia2/my/path
|
||||
// As base URL also contains /thelia2 (e.g. http://some.server.com/thelia2), we end up with
|
||||
// http://some.server.com/thelia2/thelia2/my/path, instead of http://some.server.com/thelia2/my/path
|
||||
// We have to compensate for this.
|
||||
$rcbu = $this->requestContext->getBaseUrl();
|
||||
|
||||
$hasSubdirectory = ! empty($rcbu) && (0 === strpos($path, $rcbu));
|
||||
|
||||
$base_url = $this->getBaseUrl($hasSubdirectory);
|
||||
|
||||
/* Seems no longer required
|
||||
// TODO fix this ugly patch
|
||||
if (strpos($path, "index_dev.php")) {
|
||||
$path = str_replace('index_dev.php', '', $path);
|
||||
}
|
||||
*/
|
||||
|
||||
// If only a path is requested, be sure to remove the script name (index.php or index_dev.php), if any.
|
||||
if ($path_only == self::PATH_TO_FILE) {
|
||||
if (substr($base_url, -3) == 'php') {
|
||||
$base_url = dirname($base_url);
|
||||
}
|
||||
}
|
||||
|
||||
// Normalize the given path
|
||||
$base = rtrim($base_url, '/') . '/' . ltrim($path, '/');
|
||||
} else {
|
||||
$base = $path;
|
||||
}
|
||||
|
||||
$base = str_replace('&', '&', $base);
|
||||
|
||||
$queryString = '';
|
||||
$anchor = '';
|
||||
|
||||
if (! is_null($parameters)) {
|
||||
foreach ($parameters as $name => $value) {
|
||||
// Remove this parameter from base URL to prevent duplicate parameters
|
||||
$base = preg_replace('`([?&])'.preg_quote($name, '`').'=(?:[^&]*)(?:&|$)`', '$1', $base);
|
||||
|
||||
$queryString .= sprintf("%s=%s&", urlencode($name), urlencode($value));
|
||||
}
|
||||
}
|
||||
|
||||
if ('' !== $queryString = rtrim($queryString, "&")) {
|
||||
// url could contain anchor
|
||||
$pos = strrpos($base, '#');
|
||||
if ($pos !== false) {
|
||||
$anchor = substr($base, $pos);
|
||||
$base = substr($base, 0, $pos);
|
||||
}
|
||||
|
||||
$base = rtrim($base, "?&");
|
||||
|
||||
$sepChar = strstr($base, '?') === false ? '?' : '&';
|
||||
|
||||
$queryString = $sepChar . $queryString;
|
||||
}
|
||||
|
||||
return $base . $queryString . $anchor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Absolute URL to a administration view
|
||||
*
|
||||
* @param string $viewName the view name (e.g. login for login.html)
|
||||
* @param mixed $parameters An array of parameters
|
||||
*
|
||||
* @return string The generated URL
|
||||
*/
|
||||
public function adminViewUrl($viewName, array $parameters = array())
|
||||
{
|
||||
$path = sprintf("%s/admin/%s", $this->getIndexPage(), $viewName);
|
||||
|
||||
return $this->absoluteUrl($path, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Absolute URL to a view
|
||||
*
|
||||
* @param string $viewName the view name (e.g. login for login.html)
|
||||
* @param mixed $parameters An array of parameters
|
||||
*
|
||||
* @return string The generated URL
|
||||
*/
|
||||
public function viewUrl($viewName, array $parameters = array())
|
||||
{
|
||||
$path = sprintf("?view=%s", $viewName);
|
||||
|
||||
return $this->absoluteUrl($path, $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a rewritten URL from a view, a view id and a locale
|
||||
*
|
||||
* @param $view
|
||||
* @param $viewId
|
||||
* @param $viewLocale
|
||||
*
|
||||
* @return RewritingRetriever You can access $url and $rewrittenUrl properties
|
||||
*/
|
||||
public function retrieve($view, $viewId, $viewLocale)
|
||||
{
|
||||
if (ConfigQuery::isRewritingEnable()) {
|
||||
$this->retriever->loadViewUrl($view, $viewLocale, $viewId);
|
||||
} else {
|
||||
$allParametersWithoutView = array();
|
||||
$allParametersWithoutView['lang'] = $viewLocale;
|
||||
if (null !== $viewId) {
|
||||
$allParametersWithoutView[$view . '_id'] = $viewId;
|
||||
}
|
||||
$this->retriever->rewrittenUrl = null;
|
||||
$this->retriever->url = URL::getInstance()->viewUrl($view, $allParametersWithoutView);
|
||||
}
|
||||
|
||||
return $this->retriever;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a rewritten URL from the current GET parameters
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return RewritingRetriever You can access $url and $rewrittenUrl properties or use toString method
|
||||
*/
|
||||
public function retrieveCurrent(Request $request)
|
||||
{
|
||||
if (ConfigQuery::isRewritingEnable()) {
|
||||
$view = $request->attributes->get('_view', null);
|
||||
|
||||
$viewLocale = $this->getViewLocale($request);
|
||||
|
||||
$viewId = $view === null ? null : $request->query->get($view . '_id', null);
|
||||
|
||||
$allOtherParameters = $request->query->all();
|
||||
if ($view !== null) {
|
||||
unset($allOtherParameters['view']);
|
||||
if ($viewId !== null) {
|
||||
unset($allOtherParameters[$view . '_id']);
|
||||
}
|
||||
}
|
||||
if ($viewLocale !== null) {
|
||||
unset($allOtherParameters['lang']);
|
||||
unset($allOtherParameters['locale']);
|
||||
}
|
||||
|
||||
$this->retriever->loadSpecificUrl($view, $viewLocale, $viewId, $allOtherParameters);
|
||||
} else {
|
||||
$allParametersWithoutView = $request->query->all();
|
||||
$view = $request->attributes->get('_view');
|
||||
if (isset($allOtherParameters['view'])) {
|
||||
unset($allOtherParameters['view']);
|
||||
}
|
||||
$this->retriever->rewrittenUrl = null;
|
||||
$this->retriever->url = URL::getInstance()->viewUrl($view, $allParametersWithoutView);
|
||||
}
|
||||
|
||||
return $this->retriever;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a rewritten URL from the current GET parameters or use toString method
|
||||
*
|
||||
* @param $url
|
||||
*
|
||||
* @return RewritingResolver
|
||||
*/
|
||||
public function resolve($url)
|
||||
{
|
||||
$this->resolver->load($url);
|
||||
|
||||
return $this->resolver;
|
||||
}
|
||||
|
||||
protected function sanitize($string, $force_lowercase = true, $alphabetic_only = false)
|
||||
{
|
||||
static $strip = array("~", "`", "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "_", "=", "+", "[", "{", "]",
|
||||
"}", "\\", "|", ";", ":", "\"", "'", "‘", "’", "“", "”", "–", "—",
|
||||
"—", "–", ",", "<", ".", ">", "/", "?");
|
||||
|
||||
$clean = trim(str_replace($strip, "", strip_tags($string)));
|
||||
|
||||
$clean = preg_replace('/\s+/', "-", $clean);
|
||||
|
||||
$clean = ($alphabetic_only) ? preg_replace("/[^a-zA-Z0-9]/", "", $clean) : $clean ;
|
||||
|
||||
return ($force_lowercase) ?
|
||||
(function_exists('mb_strtolower')) ?
|
||||
mb_strtolower($clean, 'UTF-8') :
|
||||
strtolower($clean) :
|
||||
$clean;
|
||||
}
|
||||
|
||||
public static function checkUrl($url, array $protocols = ["http", "https"])
|
||||
{
|
||||
$pattern = sprintf(UrlValidator::PATTERN, implode('|', $protocols));
|
||||
|
||||
return (bool) preg_match($pattern, $url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the locale code from the lang attribute in URL.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return null|string
|
||||
*/
|
||||
private function getViewLocale(Request $request)
|
||||
{
|
||||
$viewLocale = $request->query->get('lang', null);
|
||||
if (null === $viewLocale) {
|
||||
// fallback for old parameter
|
||||
$viewLocale = $request->query->get('locale', null);
|
||||
}
|
||||
|
||||
return $viewLocale;
|
||||
}
|
||||
}
|
||||
73
core/lib/Thelia/Tools/Version/Constraints/BaseConstraint.php
Normal file
73
core/lib/Thelia/Tools/Version/Constraints/BaseConstraint.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace Thelia\Tools\Version\Constraints;
|
||||
|
||||
/**
|
||||
* Class BaseConstraint
|
||||
* @package Thelia\Tools\Version\Constraints
|
||||
* @author Julien Chanséaume <jchanseaume@openstudio.fr>
|
||||
*/
|
||||
abstract class BaseConstraint implements ConstraintInterface
|
||||
{
|
||||
protected $operator = "=";
|
||||
|
||||
protected $expression = null;
|
||||
|
||||
public function __construct($expression)
|
||||
{
|
||||
$this->expression = $expression;
|
||||
}
|
||||
|
||||
public function test($version, $strict = false)
|
||||
{
|
||||
$version = $this->normalize($version, $strict);
|
||||
|
||||
return version_compare($version, $this->expression, $this->operator);
|
||||
}
|
||||
|
||||
public function normalize($version, $strict = false)
|
||||
{
|
||||
return $strict ? $version : $this->normalizePrecision($version);
|
||||
}
|
||||
|
||||
protected function normalizePrecision($version, $changeExpression = true)
|
||||
{
|
||||
$expressionElements = preg_split('/[\.\-]/', $this->expression);
|
||||
// cleaning alpha RC beta
|
||||
$version = preg_replace('/\-.*$/', '', $version);
|
||||
$versionElements = preg_split('/\./', $version);
|
||||
|
||||
if (count($expressionElements) < count($versionElements)) {
|
||||
if (true === $changeExpression) {
|
||||
$this->expression = implode(
|
||||
'.',
|
||||
array_merge(
|
||||
$expressionElements,
|
||||
array_fill(
|
||||
count($expressionElements) - 1,
|
||||
count($versionElements) - count($expressionElements),
|
||||
'0'
|
||||
)
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$version = implode(
|
||||
'.',
|
||||
array_slice($versionElements, 0, count($expressionElements))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $version;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace Thelia\Tools\Version\Constraints;
|
||||
|
||||
/**
|
||||
* Class ConstraintEqual
|
||||
* @package Thelia\Tools\Version\Constraints
|
||||
* @author Julien Chanséaume <jchanseaume@openstudio.fr>
|
||||
*/
|
||||
class ConstraintEqual extends BaseConstraint
|
||||
{
|
||||
public function __construct($expression)
|
||||
{
|
||||
$this->expression = str_replace('=', '', $expression);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace Thelia\Tools\Version\Constraints;
|
||||
|
||||
/**
|
||||
* Class ConstraintGreater
|
||||
* @package Thelia\Tools\Version\Constraints
|
||||
* @author Julien Chanséaume <jchanseaume@openstudio.fr>
|
||||
*/
|
||||
class ConstraintGreater extends BaseConstraint
|
||||
{
|
||||
public function __construct($expression, $strict = false)
|
||||
{
|
||||
$this->operator = $strict ? ">" : ">=";
|
||||
$this->expression = substr(
|
||||
$expression,
|
||||
strlen($this->operator)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace Thelia\Tools\Version\Constraints;
|
||||
|
||||
/**
|
||||
* Class ContraintInterface
|
||||
* @package Thelia\Tools\Version\Constraints
|
||||
* @author Julien Chanséaume <jchanseaume@openstudio.fr>
|
||||
*/
|
||||
interface ConstraintInterface
|
||||
{
|
||||
/**
|
||||
* Normalize a version number in a version that will be used in `version_compare`
|
||||
*
|
||||
* @param string $version the version expression
|
||||
* @return string the normalized expression
|
||||
*/
|
||||
public function normalize($version, $strict = false);
|
||||
|
||||
/**
|
||||
* Test if the version number is valid
|
||||
*
|
||||
* @param string $version the version number
|
||||
* @param bool $strict if false precision will be normalized. eg: 2.1.0 > 2.1 will become 2.1.0 > 2.1.0 (default false)
|
||||
* @return bool true if the version is equal, otherwise false
|
||||
*/
|
||||
public function test($version, $strict = false);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace Thelia\Tools\Version\Constraints;
|
||||
|
||||
/**
|
||||
* Class ConstraintLower
|
||||
* @package Thelia\Tools\Version\Constraints
|
||||
* @author Julien Chanséaume <jchanseaume@openstudio.fr>
|
||||
*/
|
||||
class ConstraintLower extends BaseConstraint
|
||||
{
|
||||
public function __construct($expression, $strict = false)
|
||||
{
|
||||
$this->operator = $strict ? "<" : "<=";
|
||||
$this->expression = substr(
|
||||
$expression,
|
||||
strlen($this->operator)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
namespace Thelia\Tools\Version\Constraints;
|
||||
|
||||
/**
|
||||
* Class ConstraintNearlyEqual
|
||||
* @package Thelia\Tools\Version\Constraints
|
||||
* @author Julien Chanséaume <jchanseaume@openstudio.fr>
|
||||
*/
|
||||
class ConstraintNearlyEqual extends BaseConstraint
|
||||
{
|
||||
public function __construct($expression)
|
||||
{
|
||||
$this->expression = str_replace('~', '', $expression);
|
||||
}
|
||||
|
||||
public function normalize($version, $strict = false)
|
||||
{
|
||||
if (!$strict) {
|
||||
$version = $this->normalizePrecision($version, false);
|
||||
}
|
||||
|
||||
return $version;
|
||||
}
|
||||
}
|
||||
134
core/lib/Thelia/Tools/Version/Version.php
Normal file
134
core/lib/Thelia/Tools/Version/Version.php
Normal file
@@ -0,0 +1,134 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
|
||||
namespace Thelia\Tools\Version;
|
||||
|
||||
use Thelia\Tools\Version\Constraints\ConstraintEqual;
|
||||
use Thelia\Tools\Version\Constraints\ConstraintGreater;
|
||||
use Thelia\Tools\Version\Constraints\ConstraintInterface;
|
||||
use Thelia\Tools\Version\Constraints\ConstraintLower;
|
||||
use Thelia\Tools\Version\Constraints\ConstraintNearlyEqual;
|
||||
|
||||
/**
|
||||
* Class Version
|
||||
* @package Thelia\Tools
|
||||
* @author Julien Chanséaume <jchanseaume@openstudio.fr>
|
||||
*/
|
||||
class Version
|
||||
{
|
||||
/**
|
||||
* Test if a version matched the version contraints.
|
||||
*
|
||||
* constraints can be simple or complex (multiple constraints separated by space) :
|
||||
*
|
||||
* - "~2.1" : version 2.1.*
|
||||
* - "~2.1 <=2.1.4" : version 2.1.* but lower or equal to 2.1.4
|
||||
* - ">=2.1" : version 2.1.*, 2.2, ...
|
||||
* - ">2.1.1 <=2.1.5" : version greater than 2.1.1 but lower or equal than 2.1.5
|
||||
* - ...
|
||||
*
|
||||
* @param string $version the version to test
|
||||
* @param string $constraints the versions constraints
|
||||
* @param bool $strict if true 2.1 is different of 2.1.0, if false version are normalized so 2.1
|
||||
* will be expended to 2.1.0
|
||||
* @param string $defaultComparison the default comparison if nothing provided
|
||||
* @return bool true if version matches the constraints
|
||||
*/
|
||||
public static function test($version, $constraints, $strict = false, $defaultComparison = "=")
|
||||
{
|
||||
$constraints = self::parseConstraints($constraints, $defaultComparison);
|
||||
|
||||
/** @var ConstraintInterface $constraint */
|
||||
foreach ($constraints as $constraint) {
|
||||
if (!$constraint->test($version, $strict)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static function parseConstraints($constraints, $defaultComparison = "=")
|
||||
{
|
||||
$constraintsList = [];
|
||||
|
||||
foreach (explode(" ", $constraints) as $expression) {
|
||||
if (1 === preg_match('/^[0-9]/', $expression)) {
|
||||
$expression = $defaultComparison . $expression;
|
||||
}
|
||||
|
||||
if (strpos($expression, '>=') !== false) {
|
||||
$constraint = new ConstraintGreater($expression);
|
||||
} elseif (strpos($expression, '>') !== false) {
|
||||
$constraint = new ConstraintGreater($expression, true);
|
||||
} elseif (strpos($expression, '<=') !== false) {
|
||||
$constraint = new ConstraintLower($expression);
|
||||
} elseif (strpos($expression, '<') !== false) {
|
||||
$constraint = new ConstraintLower($expression, true);
|
||||
} elseif (strpos($expression, '~') !== false) {
|
||||
$constraint = new ConstraintNearlyEqual($expression);
|
||||
} else {
|
||||
$constraint = new ConstraintEqual($expression);
|
||||
}
|
||||
|
||||
$constraintsList[] = $constraint;
|
||||
}
|
||||
|
||||
return $constraintsList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Split a version into an associative array
|
||||
* [version, major, minus, release, extra]
|
||||
*
|
||||
* @param string $version the version to split
|
||||
* @return array associative array
|
||||
* [
|
||||
* 'version' => 'digit',
|
||||
* 'major' => 'digit',
|
||||
* 'minus' => 'digit',
|
||||
* 'release' => 'digit',
|
||||
* 'extra' => 'alphanumeric'
|
||||
* ]
|
||||
*/
|
||||
public static function parse($version = null)
|
||||
{
|
||||
if (is_null($version)) {
|
||||
$version = \Thelia\Core\Thelia::THELIA_VERSION;
|
||||
}
|
||||
|
||||
$pattern = "`^(?<version>
|
||||
(?<major>[0-9]+)\.
|
||||
(?<minus>[0-9]+)\.
|
||||
(?<release>[0-9]+)
|
||||
-?(?<extra>[a-zA-Z0-9]*) # extra_version will also match empty string
|
||||
)$`x";
|
||||
|
||||
if (!preg_match($pattern, $version, $match)) {
|
||||
throw new \InvalidArgumentException(
|
||||
sprintf(
|
||||
"Invalid version number provided : %s".PHP_EOL,
|
||||
$version
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return [
|
||||
'version' => $match['version'],
|
||||
'major' => $match['major'],
|
||||
'minus' => $match['minus'],
|
||||
'release' => $match['release'],
|
||||
'extra' => $match['extra'],
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user