Skip to content

Commit

Permalink
Merge pull request #10 from lopes-vincent/master
Browse files Browse the repository at this point in the history
Add image type
  • Loading branch information
gillesbourgeat authored Feb 4, 2019
2 parents a483cdf + b27d5c3 commit 75c5ffc
Show file tree
Hide file tree
Showing 27 changed files with 974 additions and 106 deletions.
13 changes: 13 additions & 0 deletions Action/AttributeTypeAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,16 @@ public function metaUpdate(AttributeTypeAvMetaEvent $event)
$event->getAttributeTypeAvMeta()->save($event->getConnectionInterface());
}

/**
* @param AttributeTypeAvMetaEvent $event
* @throws \Exception
* @throws \Propel\Runtime\Exception\PropelException
*/
public function metaDelete(AttributeTypeAvMetaEvent $event)
{
$event->getAttributeTypeAvMeta()->delete($event->getConnectionInterface());
}

/**
* Returns an array of event names this subscriber wants to listen to.
*
Expand Down Expand Up @@ -141,6 +151,9 @@ public static function getSubscribedEvents()
),
AttributeTypeEvents::ATTRIBUTE_TYPE_AV_META_UPDATE => array(
'metaUpdate', 128
),
AttributeTypeEvents::ATTRIBUTE_TYPE_AV_META_DELETE => array(
'metaDelete', 128
)
);
}
Expand Down
26 changes: 26 additions & 0 deletions AttributeType.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
namespace AttributeType;

use Propel\Runtime\Connection\ConnectionInterface;
use Symfony\Component\Finder\Finder;
use Thelia\Core\Template\TemplateDefinition;
use Thelia\Module\BaseModule;
use Thelia\Install\Database;
Expand All @@ -28,6 +29,11 @@ class AttributeType extends BaseModule

const RESERVED_SLUG = 'id,attribute_id,id_translater,locale,title,chapo,description,postscriptum,position';

const ATTRIBUTE_TYPE_AV_IMAGE_FOLDER = 'attribute_type_av_images';

/** @var string */
const UPDATE_PATH = __DIR__ . DS . 'Config' . DS . 'update';

/**
* @param ConnectionInterface $con
*/
Expand All @@ -40,6 +46,26 @@ public function postActivation(ConnectionInterface $con = null)
}
}

/**
* @param $currentVersion
* @param $newVersion
* @param ConnectionInterface|null $con
*/
public function update($currentVersion, $newVersion, ConnectionInterface $con = null)
{
$finder = (new Finder())->files()->name('#.*?\.sql#')->sortByName()->in(self::UPDATE_PATH);
if ($finder->count() === 0) {
return;
}
$database = new Database($con);
/** @var \Symfony\Component\Finder\SplFileInfo $updateSQLFile */
foreach ($finder as $updateSQLFile) {
if (version_compare($currentVersion, str_replace('.sql', '', $updateSQLFile->getFilename()), '<')) {
$database->insertSql(null, [$updateSQLFile->getPathname()]);
}
}
}

/**
* @return array
*/
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 1.3.0

- Add image field type (with uploads !)

# 1.2.3

- Resolve #8 Add method addOutputFields
Expand Down
4 changes: 2 additions & 2 deletions Config/insert.sql
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
SELECT @max_id := IFNULL(MAX(`id`),0) FROM `attribute_type`;

INSERT INTO `attribute_type` (`id`, `slug`, `has_attribute_av_value`, `is_multilingual_attribute_av_value`, `pattern`, `css_class`, `input_type`, `max`, `min`, `step`, `created_at`, `updated_at`) VALUES
(@max_id + 1, 'color', 1, 0, '#([a-f]|[A-F]|[0-9]){3}(([a-f]|[A-F]|[0-9]){3})?\\\\b', NULL, 'color', NULL, NULL, NULL, NOW(), NOW());
INSERT INTO `attribute_type` (`id`, `slug`, `has_attribute_av_value`, `is_multilingual_attribute_av_value`, `pattern`, `css_class`, `input_type`, `max`, `min`, `step`, `image_max_width`, `image_max_height`, `image_ratio`, `created_at`, `updated_at`) VALUES
(@max_id + 1, 'color', 1, 0, '#([a-f]|[A-F]|[0-9]){3}(([a-f]|[A-F]|[0-9]){3})?\\\\b', NULL, 'color', NULL, NULL, NULL, NULL, NULL, NULL, NOW(), NOW());

INSERT INTO `attribute_type_i18n` (`id`, `locale`, `title`, `description`) VALUES
(@max_id + 1, 'cs_CZ', 'barva', 'hexadecimální barva'),
Expand Down
2 changes: 1 addition & 1 deletion Config/module.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<language>en_US</language>
<language>fr_FR</language>
</languages>
<version>1.2.3</version>
<version>1.3.0</version>
<author>
<name>Gilles Bourgeat</name>
<email>gilles.bourgeat@gmail.com</email>
Expand Down
9 changes: 9 additions & 0 deletions Config/routing.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,13 @@
<requirement key="attribute_id">\d+</requirement>
</route>

<route id="attribute_type_meta_delete" path="/admin/attribute-type-av-meta/{attribute_id}/{attribute_type_id}/{attribute_av_id}/{lang_id}/{method}" methods="POST">
<default key="_controller">AttributeType\Controller\AttributeTypeAttributeAvController::deleteMetaAction</default>
<requirement key="attribute_id">\d+</requirement>
<requirement key="attribute_type_id">\d+</requirement>
<requirement key="attribute_av_id">\d+</requirement>
<requirement key="lang_id">\d+</requirement>
<requirement key="method">_delete</requirement>
</route>

</routes>
3 changes: 3 additions & 0 deletions Config/schema.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
<column name="max" type="FLOAT" />
<column name="min" type="FLOAT" />
<column name="step" type="FLOAT" />
<column name="image_max_width" type="FLOAT" />
<column name="image_max_height" type="FLOAT" />
<column name="image_ratio" type="FLOAT" />
<column name="title" size="255" type="VARCHAR" />
<column name="description" type="CLOB" />

Expand Down
19 changes: 15 additions & 4 deletions Config/thelia.sql
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ SET FOREIGN_KEY_CHECKS = 0;
-- attribute_type
-- ---------------------------------------------------------------------

CREATE TABLE IF NOT EXISTS `attribute_type`
DROP TABLE IF EXISTS `attribute_type`;

CREATE TABLE `attribute_type`
(
`id` INTEGER NOT NULL AUTO_INCREMENT,
`slug` VARCHAR(50),
Expand All @@ -19,6 +21,9 @@ CREATE TABLE IF NOT EXISTS `attribute_type`
`max` FLOAT,
`min` FLOAT,
`step` FLOAT,
`image_max_width` FLOAT,
`image_max_height` FLOAT,
`image_ratio` FLOAT,
`created_at` DATETIME,
`updated_at` DATETIME,
PRIMARY KEY (`id`),
Expand All @@ -29,7 +34,9 @@ CREATE TABLE IF NOT EXISTS `attribute_type`
-- attribute_attribute_type
-- ---------------------------------------------------------------------

CREATE TABLE IF NOT EXISTS `attribute_attribute_type`
DROP TABLE IF EXISTS `attribute_attribute_type`;

CREATE TABLE `attribute_attribute_type`
(
`id` INTEGER NOT NULL AUTO_INCREMENT,
`attribute_id` INTEGER NOT NULL,
Expand All @@ -53,7 +60,9 @@ CREATE TABLE IF NOT EXISTS `attribute_attribute_type`
-- attribute_type_av_meta
-- ---------------------------------------------------------------------

CREATE TABLE IF NOT EXISTS `attribute_type_av_meta`
DROP TABLE IF EXISTS `attribute_type_av_meta`;

CREATE TABLE `attribute_type_av_meta`
(
`id` INTEGER NOT NULL AUTO_INCREMENT,
`attribute_av_id` INTEGER NOT NULL,
Expand All @@ -79,7 +88,9 @@ CREATE TABLE IF NOT EXISTS `attribute_type_av_meta`
-- attribute_type_i18n
-- ---------------------------------------------------------------------

CREATE TABLE IF NOT EXISTS `attribute_type_i18n`
DROP TABLE IF EXISTS `attribute_type_i18n`;

CREATE TABLE `attribute_type_i18n`
(
`id` INTEGER NOT NULL,
`locale` VARCHAR(5) DEFAULT 'en_US' NOT NULL,
Expand Down
4 changes: 4 additions & 0 deletions Config/update/1.3.0.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ALTER TABLE attribute_type
ADD `image_max_width` FLOAT AFTER `step`,
ADD `image_max_height` FLOAT AFTER `image_max_width`,
ADD `image_ratio` FLOAT AFTER `image_max_height`;
152 changes: 145 additions & 7 deletions Controller/AttributeTypeAttributeAvController.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,20 @@

namespace AttributeType\Controller;

use AttributeType\AttributeType;
use AttributeType\Event\AttributeTypeEvents;
use AttributeType\Event\AttributeTypeAvMetaEvent;
use AttributeType\Form\AttributeTypeAvMetaUpdateForm;
use AttributeType\Model\AttributeAttributeType;
use AttributeType\Model\AttributeAttributeTypeQuery;
use AttributeType\Model\AttributeTypeAvMeta;
use AttributeType\Model\AttributeTypeAvMetaQuery;
use AttributeType\Model\AttributeTypeQuery;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Thelia\Core\Security\AccessManager;
use Thelia\Core\Security\Resource\AdminResources;
use Thelia\Files\Exception\ProcessFileException;
use Thelia\Model\Lang;
use Thelia\Model\LangQuery;

Expand Down Expand Up @@ -52,28 +58,94 @@ public function updateMetaAction($attribute_id)
foreach ($attributeAvs as $attributeAvId => $attributeAv) {
foreach ($attributeAv['lang'] as $langId => $lang) {
foreach ($lang['attribute_type'] as $attributeTypeId => $value) {
$this->dispatchEvent(
$this->getAttributeAttributeType($attributeTypeId, $attribute_id),
$attributeAvId,
$langId,
$value
);
$values = [];
$values[$langId] = $value;
$attributeType = AttributeTypeQuery::create()
->findOneById($attributeTypeId);

if ($attributeType->getInputType() === "image") {
if (null === $value) {
continue;
}

$uploadedFileName = $this->uploadFile($value);
$values[$langId] = $uploadedFileName;

if (!$attributeType->getIsMultilingualAttributeAvValue()) {
$activeLangs = LangQuery::create()
->filterByActive(1)
->find();
/** @var Lang $lang */
foreach ($activeLangs as $lang) {
$values[$lang->getId()] = $uploadedFileName;
}
}
}

foreach ($values as $langId => $langValue) {
$this->dispatchEvent(
$this->getAttributeAttributeType($attributeTypeId, $attribute_id),
$attributeAvId,
$langId,
$langValue
);
}
}
}
}

$this->resetUpdateForm();
return $this->generateSuccessRedirect($form);
} catch (\Exception $e) {
$this->setupFormErrorContext(
$this->getTranslator()->trans("%obj modification", array('%obj' => $this->objectName)),
$e->getMessage(),
$form
$form,
$e
);

return $this->viewAttribute($attribute_id);
}
}

public function deleteMetaAction($attribute_id, $attribute_type_id, $attribute_av_id, $lang_id)
{
if (null !== $response = $this->checkAuth(array(AdminResources::ATTRIBUTE), null, AccessManager::DELETE)) {
return $response;
}
$form = $this->createForm("attribute_type.delete");
try {
$this->validateForm($form);
$attributeType = AttributeTypeQuery::create()
->findOneById($attribute_type_id);
$attributeAttributeType = $this->getAttributeAttributeType($attribute_type_id, $attribute_id);
$eventName = AttributeTypeEvents::ATTRIBUTE_TYPE_AV_META_DELETE;
$attributeAvMetaQuery = AttributeTypeAvMetaQuery::create()
->filterByAttributeAvId($attribute_av_id)
->filterByAttributeAttributeTypeId($attributeAttributeType->getId());
if ($attributeType->getIsMultilingualAttributeAvValue()) {
$attributeAvMetaQuery->filterByLocale($this->getLocale($lang_id));
}
$attributeAvMetas = $attributeAvMetaQuery->find();
foreach ($attributeAvMetas as $attributeAvMeta) {
$this->dispatch(
$eventName,
(new AttributeTypeAvMetaEvent($attributeAvMeta))
);
}
$this->resetUpdateForm();
return $this->generateSuccessRedirect($form);
} catch (\Exception $e) {
$this->setupFormErrorContext(
$this->getTranslator()->trans("%obj modification", array('%obj' => $this->objectName)),
$e->getMessage(),
$form,
$e
);
return $this->viewAttribute($attribute_id);
}
}

/**
* @param AttributeAttributeType $attributeAttributeType
* @param int $attributeAvId
Expand Down Expand Up @@ -148,4 +220,70 @@ protected function getLocale($langId)

return $this->langs[$langId]->getLocale();
}

/**
* @param UploadedFile $file
* @return string
*/
protected function uploadFile(UploadedFile $file)
{
if ($file->getError() == UPLOAD_ERR_INI_SIZE) {
$message = $this->getTranslator()
->trans(
'File is too large, please retry with a file having a size less than %size%.',
array('%size%' => ini_get('upload_max_filesize')),
'core'
);
throw new ProcessFileException($message, 403);
}
$validMimeTypes = [
'image/jpeg' => ["jpg", "jpeg"],
'image/png' => ["png"],
'image/gif' => ["gif"]
];
$mimeType = $file->getMimeType();
if (!isset($validMimeTypes[$mimeType])) {
$message = $this->getTranslator()
->trans(
'Only files having the following mime type are allowed: %types%',
[ '%types%' => implode(', ', array_keys($validMimeTypes))]
);
throw new ProcessFileException($message, 415);
}
$regex = "#^(.+)\.(".implode("|", $validMimeTypes[$mimeType]).")$#i";
$realFileName = $file->getClientOriginalName();
if (!preg_match($regex, $realFileName)) {
$message = $this->getTranslator()
->trans(
"There's a conflict between your file extension \"%ext\" and the mime type \"%mime\"",
[
'%mime' => $mimeType,
'%ext' => $file->getClientOriginalExtension()
]
);
throw new ProcessFileException($message, 415);
}
$fileSystem = new Filesystem();
$fileSystem->mkdir(THELIA_WEB_DIR. DS .AttributeType::ATTRIBUTE_TYPE_AV_IMAGE_FOLDER);
$fileName = $this->generateUniqueFileName().'_'.$realFileName;
$file->move(THELIA_WEB_DIR. DS .AttributeType::ATTRIBUTE_TYPE_AV_IMAGE_FOLDER, $fileName);
return DS . AttributeType::ATTRIBUTE_TYPE_AV_IMAGE_FOLDER. DS .$fileName;
}

/**
* @return string
*/
protected function generateUniqueFileName()
{
// md5() reduces the similarity of the file names generated by
// uniqid(), which is based on timestamps
return substr(md5(uniqid()), 0, 10);
}

protected function resetUpdateForm() {
$this->getParserContext()->remove(AttributeTypeAvMetaUpdateForm::class.':form');
$theliaFormErrors = $this->getRequest()->getSession()->get('thelia.form-errors');
unset($theliaFormErrors[AttributeTypeAvMetaUpdateForm::class.':form']);
$this->getRequest()->getSession()->set('thelia.form-errors', $theliaFormErrors);
}
}
Loading

0 comments on commit 75c5ffc

Please sign in to comment.