This commit is contained in:
Marc Ducobu 2016-03-22 14:29:41 +01:00
commit e285603e18
30 changed files with 1132 additions and 1185 deletions

View File

@ -0,0 +1,199 @@
<?php
/*
* Copyright (C) 2016 Champs-Libres <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Chill\MainBundle\Command;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Filesystem\Filesystem;
use Chill\MainBundle\Entity\PostalCode;
/**
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class LoadPostalCodesCommand extends ContainerAwareCommand
{
protected function configure()
{
$this->setName('chill:main:postal-code:populate')
->setDescription("Add the postal code from a csv file.")
->setHelp("This script will try to avoid existing postal code "
. "using the postal code and name. \n"
. "The CSV file must have the following columns: "
. "postal code, label, country code."
. "The CSV file should not have any header row.")
->addArgument('csv_file', InputArgument::REQUIRED, "the path to "
. "the csv file. See the help for specifications.")
->addOption(
'delimiter',
'd',
InputOption::VALUE_OPTIONAL,
"The delimiter character of the csv file",
",")
->addOption(
'enclosure',
null,
InputOption::VALUE_OPTIONAL,
"The enclosure character of the csv file",
'"'
)
->addOption(
'escape',
null,
InputOption::VALUE_OPTIONAL,
"The escape character of the csv file",
"\\"
)
;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
try {
$csv = $this->getCSVResource($input);
} catch (\RuntimeException $e) {
$output->writeln('<error>Error during opening the csv file : '.
$e->getMessage().'</error>');
}
if ($output->getVerbosity() === OutputInterface::VERBOSITY_VERY_VERBOSE) {
$output->writeln('The content of the file is ...');
$output->write(file_get_contents($input->getArgument('csv_file')));
}
$num = 0;
$line = 0;
while (($row = fgetcsv(
$csv,
0,
$input->getOption('delimiter'),
$input->getOption('enclosure'),
$input->getOption('escape'))) !== false) {
try{
$this->addPostalCode($row, $output);
$num++;
} catch (ExistingPostalCodeException $ex) {
$output->writeln('<warning> on line '.$line.' : '.$ex->getMessage().'</warning>');
} catch (CountryCodeNotFoundException $ex) {
$output->writeln('<warning> on line '.$line.' : '.$ex->getMessage().'</warning>');
} catch (PostalCodeNotValidException $ex) {
$output->writeln('<warning> on line '.$line.' : '.$ex->getMessage().'</warning>');
}
$line ++;
}
$this->getContainer()->get('doctrine.orm.entity_manager')->flush();
$output->writeln('<info>'.$num.' were added !</info>');
}
private function getCSVResource(InputInterface $input)
{
$fs = new Filesystem();
$filename = $input->getArgument('csv_file');
if (!$fs->exists($filename)) {
throw new \RuntimeException("The file does not exists or you do not "
. "have the right to read it.");
}
$resource = fopen($filename, 'r');
if ($resource == FALSE) {
throw new \RuntimeException("The file '$filename' could not be opened.");
}
return $resource;
}
private function addPostalCode($row, OutputInterface $output)
{
if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) {
$output->writeln('handling row: '. $row[0].' | '. $row[1].' | '. $row[2]);
}
$em = $this->getContainer()->get('doctrine.orm.entity_manager');
$country = $em
->getRepository('ChillMainBundle:Country')
->findOneBy(array('countryCode' => $row[2]));
if ($country === NULL) {
throw new CountryCodeNotFoundException(sprintf("The country with code %s is not found. Aborting to insert postal code with %s - %s",
$row[2], $row[0], $row[1]));
}
// try to find an existing postal code
$existingPC = $em
->getRepository('ChillMainBundle:PostalCode')
->findBy(array('code' => $row[0], 'name' => $row[1]));
if (count($existingPC) > 0) {
throw new ExistingPostalCodeException(sprintf("A postal code with code : %s and name : %s already exists, skipping",
$row[0], $row[1]));
}
$postalCode = (new PostalCode())
->setCode($row[0])
->setName($row[1])
->setCountry($country)
;
$errors = $this->getContainer()->get('validator')->validate($postalCode);
if ($errors->count() == 0) {
$em->persist($postalCode);
} else {
$msg = "";
foreach ($errors as $error) {
$msg .= " ".$error->getMessage();
}
throw new PostalCodeNotValidException($msg);
}
if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) {
$output->writeln(sprintf('Creating postal code with code: %s, name: %s, countryCode: %s',
$postalCode->getCode(), $postalCode->getName(), $postalCode->getCountry()->getCountryCode()));
}
}
}
class ExistingPostalCodeException extends \Exception
{
}
class CountryCodeNotFoundException extends \Exception
{
}
class PostalCodeNotValidException extends \Exception
{
}

View File

@ -0,0 +1,106 @@
<?php
/*
* Chill is a software for social workers
*
* Copyright (C) 2014-2016, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Chill\MainBundle\DataFixtures\ORM;
use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Chill\MainBundle\Entity\PostalCode;
/**
* Description of LoadPostalCodes
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* @author Champs Libres <info@champs-libres.coop>
*/
class LoadPostalCodes extends AbstractFixture implements OrderedFixtureInterface
{
public function getOrder()
{
return 50;
}
public static $refs = array();
public function load(ObjectManager $manager)
{
$lines = str_getcsv(self::$codes, "\n");
$belgium = $manager->getRepository('ChillMainBundle:Country')
->findOneBy(array('countryCode' => 'BE'));
foreach($lines as $line) {
$code = str_getcsv($line);
$c = new PostalCode();
$c->setCountry($belgium)
->setCode($code[0])
->setName(implode(' - ', array(
ucwords(strtolower($code[1])), strtoupper($code[2]),
)));
$manager->persist($c);
$ref = 'postal_code_'.$code[0];
if (! $this->hasReference($ref)) {
$this->addReference($ref, $c);
self::$refs[] = $ref;
}
}
$manager->flush();
}
private static $codes = <<<EOF
1000,BRUXELLES,BRUXELLES,Bruxelles
1020,Laeken,BRUXELLES,Bruxelles
1030,SCHAERBEEK,SCHAERBEEK,Bruxelles
1040,ETTERBEEK,ETTERBEEK,Bruxelles
1050,IXELLES,IXELLES,Bruxelles
1060,SAINT-GILLES,SAINT-GILLES,Bruxelles
1070,ANDERLECHT,ANDERLECHT,Bruxelles
1080,MOLENBEEK-SAINT-JEAN,MOLENBEEK-SAINT-JEAN,Bruxelles
1081,KOEKELBERG,KOEKELBERG,Bruxelles
1082,BERCHEM-SAINTE-AGATHE,BERCHEM-SAINTE-AGATHE,Bruxelles
1083,GANSHOREN,GANSHOREN,Bruxelles
1090,JETTE,JETTE,Bruxelles
1120,Neder-Over-Heembeek,BRUXELLES,Bruxelles
1130,Haren,BRUXELLES,Bruxelles
1140,EVERE,EVERE,Bruxelles
1150,WOLUWE-SAINT-PIERRE,WOLUWE-SAINT-PIERRE,Bruxelles
1160,AUDERGHEM,AUDERGHEM,Bruxelles
1170,WATERMAEL-BOITSFORT,WATERMAEL-BOITSFORT,Bruxelles
1180,UCCLE,UCCLE,Bruxelles
1190,FOREST,FOREST,Bruxelles
1200,WOLUWE-SAINT-LAMBERT,WOLUWE-SAINT-LAMBERT,Bruxelles
1210,SAINT-JOSSE-TEN-NOODE,SAINT-JOSSE-TEN-NOODE,Bruxelles
1300,Limal,WAVRE,Brabant-Wallon
1300,WAVRE,WAVRE,Brabant-Wallon
1301,Bierges,WAVRE,Brabant-Wallon
1310,LA HULPE,LA HULPE,Brabant-Wallon
1315,Glimes,INCOURT,Brabant-Wallon
1315,INCOURT,INCOURT,Brabant-Wallon
1315,Opprebais,INCOURT,Brabant-Wallon
1315,Piètrebais,INCOURT,Brabant-Wallon
1315,Roux-Miroir,INCOURT,Brabant-Wallon
1320,BEAUVECHAIN,BEAUVECHAIN,Brabant-Wallon
EOF;
}

146
Entity/Address.php Normal file
View File

@ -0,0 +1,146 @@
<?php
namespace Chill\MainBundle\Entity;
/**
* Address
*/
class Address
{
/**
* @var integer
*/
private $id;
/**
* @var string
*/
private $streetAddress1 = '';
/**
* @var string
*/
private $streetAddress2 = '';
/**
* @var \Chill\MainBundle\Entity\PostalCode
*/
private $postcode;
/**
*
* @var \DateTime
*/
private $validFrom;
public function __construct()
{
$this->validFrom = new \DateTime();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set streetAddress1
*
* @param string $streetAddress1
*
* @return Address
*/
public function setStreetAddress1($streetAddress1)
{
$this->streetAddress1 = $streetAddress1 === NULL ? '' : $streetAddress1;
return $this;
}
/**
* Get streetAddress1
*
* @return string
*/
public function getStreetAddress1()
{
return $this->streetAddress1;
}
/**
* Set streetAddress2
*
* @param string $streetAddress2
*
* @return Address
*/
public function setStreetAddress2($streetAddress2)
{
$this->streetAddress2 = $streetAddress2 === NULL ? '' : $streetAddress2;
return $this;
}
/**
* Get streetAddress2
*
* @return string
*/
public function getStreetAddress2()
{
return $this->streetAddress2;
}
/**
* Set postcode
*
* @param \Chill\MainBundle\Entity\PostalCode $postcode
*
* @return Address
*/
public function setPostcode(\Chill\MainBundle\Entity\PostalCode $postcode = null)
{
$this->postcode = $postcode;
return $this;
}
/**
* Get postcode
*
* @return \Chill\MainBundle\Entity\PostalCode
*/
public function getPostcode()
{
return $this->postcode;
}
/**
*
* @return \DateTime
*/
public function getValidFrom()
{
return $this->validFrom;
}
/**
*
* @param \DateTime $validFrom
* @return \Chill\MainBundle\Entity\Address
*/
public function setValidFrom(\DateTime $validFrom)
{
$this->validFrom = $validFrom;
return $this;
}
}

113
Entity/PostalCode.php Normal file
View File

@ -0,0 +1,113 @@
<?php
namespace Chill\MainBundle\Entity;
/**
* PostalCode
*/
class PostalCode
{
/**
* @var integer
*/
private $id;
/**
* @var string
*/
private $name;
/**
* @var string
*/
private $code;
/**
* @var \Chill\MainBundle\Entity\Country
*/
private $country;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
*
* @return PostalCode
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Set code
*
* @param string $code
*
* @return PostalCode
*/
public function setCode($code)
{
$this->code = $code;
return $this;
}
/**
* Get code
*
* @return string
*/
public function getCode()
{
return $this->code;
}
/**
* Set country
*
* @param \Chill\MainBundle\Entity\Country $country
*
* @return PostalCode
*/
public function setCountry(\Chill\MainBundle\Entity\Country $country = null)
{
$this->country = $country;
return $this;
}
/**
* Get country
*
* @return \Chill\MainBundle\Entity\Country
*/
public function getCountry()
{
return $this->country;
}
}

55
Form/Type/AddressType.php Normal file
View File

@ -0,0 +1,55 @@
<?php
/*
* Copyright (C) 2016 Champs-Libres <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Chill\MainBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Extension\Core\Type\TextType;
/**
* A type to create/update Address entity
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* @author Champs Libres <info@champs-libres.coop>
*/
class AddressType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('streetAddress1', TextType::class, array(
'required' => true
))
->add('streetAddress2', TextType::class, array(
'required' => false
))
->add('postCode', PostalCodeType::class, array(
'label' => 'Postal code'
))
->add('validFrom', 'date', array(
'required' => true,
'widget' => 'single_text',
'format' => 'dd-MM-yyyy'
)
)
;
}
}

View File

@ -0,0 +1,64 @@
<?php
/*
* Copyright (C) 2016 Champs-Libres <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Chill\MainBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\FormBuilderInterface;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\MainBundle\Entity\PostalCode;
/**
* A form to pick between PostalCode
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
* @author Champs Libres <info@champs-libres.coop>
*/
class PostalCodeType extends AbstractType
{
/**
*
* @var TranslatableStringHelper
*/
protected $translatableStringHelper;
public function __construct(TranslatableStringHelper $helper)
{
$this->translatableStringHelper = $helper;
}
public function getParent()
{
return \Symfony\Bridge\Doctrine\Form\Type\EntityType::class;
}
public function configureOptions(OptionsResolver $resolver)
{
// create a local copy for usage in Closure
$helper = $this->translatableStringHelper;
$resolver->setDefault('class', PostalCode::class)
->setDefault('choice_label', function(PostalCode $code) use ($helper) {
return $code->getCode().' '.$code->getName().' ['.
$helper->localize($code->getCountry()->getName()).']';
}
);
}
}

View File

@ -21,7 +21,7 @@
namespace Chill\MainBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
/**
* Extends choice to allow adding select2 library on widget
@ -40,7 +40,7 @@ class Select2EntityType extends AbstractType
return 'entity';
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
public function configureOptions(OptionsResolver $resolver)
{
$resolver->replaceDefaults(
array('attr' => array('class' => 'select2 '))

View File

@ -100,7 +100,7 @@ module.exports = function(grunt) {
sass: {
dist: {
options: {
debugInfo: true,
debugInfo: false,
},
files: [{
expand: true,

View File

@ -0,0 +1,22 @@
Chill\MainBundle\Entity\Address:
type: entity
table: chill_main_address
id:
id:
type: integer
id: true
generator:
strategy: AUTO
fields:
streetAddress1:
type: string
length: 255
streetAddress2:
type: string
length: 255
validFrom:
type: date
manyToOne:
postcode:
targetEntity: Chill\MainBundle\Entity\PostalCode
lifecycleCallbacks: { }

View File

@ -1,6 +1,9 @@
Chill\MainBundle\Entity\Country:
type: entity
table: null
cache:
usage: READ_ONLY
region: country_cache_region
fields:
id:
type: integer

View File

@ -1,6 +1,9 @@
Chill\MainBundle\Entity\GroupCenter:
type: entity
table: group_centers
cache:
usage: NONSTRICT_READ_WRITE
region: acl_cache_region
id:
id:
type: integer
@ -11,5 +14,9 @@ Chill\MainBundle\Entity\GroupCenter:
center:
targetEntity: Chill\MainBundle\Entity\Center
inversedBy: groupCenters
cache:
usage: NONSTRICT_READ_WRITE
permissionsGroup:
targetEntity: Chill\MainBundle\Entity\PermissionsGroup
targetEntity: Chill\MainBundle\Entity\PermissionsGroup
cache:
usage: NONSTRICT_READ_WRITE

View File

@ -1,6 +1,9 @@
Chill\MainBundle\Entity\Language:
type: entity
table: null
cache:
usage: READ_ONLY
region: language_cache_region
id:
id:
type: string

View File

@ -1,6 +1,9 @@
Chill\MainBundle\Entity\PermissionsGroup:
type: entity
table: permission_groups
cache:
usage: NONSTRICT_READ_WRITE
region: acl_cache_region
id:
id:
type: integer
@ -14,4 +17,6 @@ Chill\MainBundle\Entity\PermissionsGroup:
manyToMany:
roleScopes:
targetEntity: Chill\MainBundle\Entity\RoleScope
cache:
usage: NONSTRICT_READ_WRITE

View File

@ -0,0 +1,21 @@
Chill\MainBundle\Entity\PostalCode:
type: entity
table: chill_main_postal_code
id:
id:
type: integer
id: true
generator:
strategy: AUTO
fields:
name:
type: string
length: 255
column: label
code:
type: string
length: 100
manyToOne:
country:
targetEntity: Chill\MainBundle\Entity\Country
lifecycleCallbacks: { }

View File

@ -1,6 +1,9 @@
Chill\MainBundle\Entity\RoleScope:
type: entity
table: role_scopes
cache:
usage: NONSTRICT_READ_WRITE
region: acl_cache_region
id:
id:
type: integer
@ -15,4 +18,7 @@ Chill\MainBundle\Entity\RoleScope:
scope:
targetEntity: Chill\MainBundle\Entity\Scope
inversedBy: roleScopes
nullable: true
nullable: true
cache:
usage: NONSTRICT_READ_WRITE

View File

@ -1,6 +1,9 @@
Chill\MainBundle\Entity\Scope:
type: entity
table: scopes
cache:
usage: NONSTRICT_READ_WRITE
region: acl_cache_region
id:
id:
type: integer
@ -13,4 +16,6 @@ Chill\MainBundle\Entity\Scope:
oneToMany:
roleScopes:
targetEntity: Chill\MainBundle\Entity\RoleScope
mappedBy: scope
mappedBy: scope
cache:
usage: NONSTRICT_READ_WRITE

View File

@ -1,6 +1,9 @@
Chill\MainBundle\Entity\User:
type: entity
table: users
cache:
usage: NONSTRICT_READ_WRITE
region: acl_cache_region
id:
id:
type: integer
@ -27,5 +30,7 @@ Chill\MainBundle\Entity\User:
manyToMany:
groupCenters:
targetEntity: Chill\MainBundle\Entity\GroupCenter
cache:
usage: NONSTRICT_READ_WRITE

View File

@ -50,10 +50,6 @@ chill_main_admin_central:
defaults: { _controller: ChillMainBundle:Admin:index }
options:
menus:
section:
order: 30
label: Admin Menu
icons: [gears]
admin_permissions:
order: 0
label: Main admin menu

View File

@ -51,6 +51,13 @@ services:
tags:
- { name: twig.extension }
chill.main.twig.delegated_block:
class: Chill\MainBundle\Templating\DelegatedBlockRenderingTwig
arguments:
- "@event_dispatcher"
tags:
- { name: twig.extension }
chill.main.twig.csv_cell:
class: Chill\MainBundle\Templating\CSVCellTwig
tags:
@ -127,3 +134,10 @@ services:
- "@translator"
tags:
- { name: validator.constraint_validator, alias: 'role_scope_scope_presence' }
chill.main.form.type.postal_code_type:
class: Chill\MainBundle\Form\Type\PostalCodeType
arguments:
- "@chill.main.helper.translatable_string"
tags:
- { name: form.type }

View File

@ -0,0 +1 @@
1000,BRUXELLES - (BRUXELLES),DDS,BRUXELLES,BRUXELLES,Bruxelles
1 1000 BRUXELLES - (BRUXELLES) DDS BRUXELLES BRUXELLES Bruxelles

View File

@ -0,0 +1,66 @@
<?php
namespace Application\Migrations;
use Doctrine\DBAL\Migrations\AbstractMigration;
use Doctrine\DBAL\Schema\Schema;
/**
* Add postal code and addresses
*/
class Version20160310122322 extends AbstractMigration
{
/**
* @param Schema $schema
*/
public function up(Schema $schema)
{
$this->abortIf($this->connection->getDatabasePlatform()->getName() != 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
$this->addSql('CREATE SEQUENCE chill_main_address_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
$this->addSql('CREATE SEQUENCE chill_main_postal_code_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
$this->addSql('CREATE TABLE chill_main_address ('
. 'id INT NOT NULL, '
. 'postcode_id INT DEFAULT NULL, '
. 'streetAddress1 VARCHAR(255) NOT NULL, '
. 'streetAddress2 VARCHAR(255) NOT NULL, '
. 'validFrom DATE NOT NULL, '
. 'PRIMARY KEY(id))');
$this->addSql('CREATE INDEX IDX_165051F6EECBFDF1 ON chill_main_address '
. '(postcode_id)');
$this->addSql('CREATE TABLE chill_main_postal_code ('
. 'id INT NOT NULL, '
. 'country_id INT DEFAULT NULL, '
. 'label VARCHAR(255) NOT NULL, '
. 'code VARCHAR(100) NOT NULL, '
. 'PRIMARY KEY(id))');
$this->addSql('CREATE INDEX IDX_6CA145FAF92F3E70 ON chill_main_postal_code '
. '(country_id)');
$this->addSql('ALTER TABLE chill_main_address ADD CONSTRAINT '
. 'FK_165051F6EECBFDF1 '
. 'FOREIGN KEY (postcode_id) '
. 'REFERENCES chill_main_postal_code (id) '
. 'NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE chill_main_postal_code ADD CONSTRAINT '
. 'FK_6CA145FAF92F3E70 '
. 'FOREIGN KEY (country_id) '
. 'REFERENCES Country (id) '
. 'NOT DEFERRABLE INITIALLY IMMEDIATE');
}
/**
* @param Schema $schema
*/
public function down(Schema $schema)
{
$this->abortIf($this->connection->getDatabasePlatform()->getName() != 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
$this->addSql('ALTER TABLE chill_main_address '
. 'DROP CONSTRAINT FK_165051F6EECBFDF1');
$this->addSql('DROP SEQUENCE chill_main_address_id_seq CASCADE');
$this->addSql('DROP SEQUENCE chill_main_postal_code_id_seq CASCADE');
$this->addSql('DROP TABLE chill_main_address');
$this->addSql('DROP TABLE chill_main_postal_code');
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,7 @@
// YOUR CUSTOM SCSS
@import 'custom/timeline';
@import 'custom/mixins/entity';
@import 'custom/activity';
html,body {
min-height:100%;
@ -147,7 +149,8 @@ div.input_with_post_text input {
}
/* <- INPUT CLASS */
dl.chill_report_view_data {
dl.chill_report_view_data,
dl.chill_view_data {
dt {
margin-top: 1.5em;
@ -168,3 +171,20 @@ dl.chill_report_view_data {
.flash_message {
margin-top: 2.5em;
}
blockquote.chill-user-quote {
border-left: 10px solid $chill-yellow;
margin: 1.5em 10px;
padding: 0.5em 10px;
quotes: "\201C""\201D""\2018""\2019";
background-color: $chill-llight-gray;
p { display: inline; }
}
.chill-no-data-statement {
font-style: italic;
}

View File

@ -0,0 +1,4 @@
span.entity.entity-activity.activity-reason {
@include entity($chill-pink, white);
}

View File

@ -0,0 +1,15 @@
@mixin entity($background-color, $color: white) {
font-variant: small-caps;
display: inline;
padding: .2em .6em .3em;
font-size: 88%;
font-weight: bold;
line-height: 1;
text-align: center;
white-space: nowrap;
vertical-align: baseline;
border-radius: .25em;
color: $color;
background-color: $background-color;
}

View File

@ -22,6 +22,12 @@ Edit: Modifier
Update: Mettre à jour
Back to the list: Retour à la liste
#addresses
Street address1: Adresse ligne 1
Street address2: Adresse ligne 2
Postal code: Code postal
Valid from: Valide à partir du
#serach
Your search is empty. Please provide search terms.: La recherche est vide. Merci de fournir des termes de recherche.
The domain %domain% is unknow. Please check your search.: Le domaine de recherche "%domain%" est inconnu. Merci de vérifier votre recherche.

View File

@ -0,0 +1,10 @@
{%- macro _render(address, options) -%}
{% set options = { 'with_valid_from' : true }|merge(options|default({})) %}
{% if address.streetAddress1 is not empty %}<span class="street street1">{{ address.streetAddress1 }}</span><br/>{% endif %}
{% if address.streetAddress2 is not empty %}<span class="street street2">{{ address.streetAddress2 }}</span><br/>{% endif %}
<span class="postalCode"><span class="code">{{ address.postCode.code }}</span> <span class="name">{{ address.postCode.name }}</span></span><br/>
<span class="country">{{ address.postCode.country.name|localize_translatable_string }}</span><br/>
{%- if options['with_valid_from'] == true -%}
<span class="address_since">{{ 'Since %date%'|trans( { '%date%' : address.validFrom|localizeddate('long', 'none') } ) }}</span>
{%- endif -%}
{%- endmacro -%}

View File

@ -0,0 +1,87 @@
<?php
/*
* Copyright (C) 2016 Champs-Libres <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Chill\MainBundle\Templating;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
/**
* Add the function `chill_delegated_block`.
*
* In a template, you can now allow rendering of a block from other bundle.
*
* The layout template must explicitly call the rendering of other block,
* with the twig function
*
* ```
* chill_delegated_block('block_name', { 'array' : 'with context' } )
* ```
*
* This will launch an event
* `Chill\MainBundle\Templating\Events\DelegatedBlockRenderingEvent` with
* the event's name 'chill_block.block_name'.
*
* You may add content to the page using the function
* `DelegatedBlockRenderingEvent::addContent`.
*
* See also the documentation of
* `Chill\MainBundle\Templating\Events\DelegatedBlockRenderingEvent`
* for usage of this event class
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class DelegatedBlockRenderingTwig extends \Twig_Extension
{
/**
*
* @var EventDispatcherInterface
*/
protected $eventDispatcher;
public function __construct(EventDispatcherInterface $eventDispatcher)
{
$this->eventDispatcher = $eventDispatcher;
}
public function getName()
{
return 'chill_main_delegated_block';
}
public function getFunctions()
{
return array(
new \Twig_SimpleFunction('chill_delegated_block',
array($this, 'renderingDelegatedBlock'),
array('is_safe' => array('html')))
);
}
public function renderingDelegatedBlock($block, array $context)
{
$event = new Events\DelegatedBlockRenderingEvent($context);
$this->eventDispatcher->dispatch('chill_block.'.$block, $event);
return $event->getContent();
}
}

View File

@ -0,0 +1,105 @@
<?php
/*
* Copyright (C) 2016 Champs-Libres <info@champs-libres.coop>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Chill\MainBundle\Templating\Events;
use Symfony\Component\EventDispatcher\Event;
/**
* This event is transmitted on event chill_block.*
*
* You may access to the context as an array :
*
* ```
* $var = $event['context_key']
* ```
*
* The documentation for the bundle where the event is launched should give
* you the context keys.
*
* The keys are read-only: if you try to update the context using array access
* (example, using `$event['context_key'] = $bar;`, an error will be thrown.
*
*
* @author Julien Fastré <julien.fastre@champs-libres.coop>
*/
class DelegatedBlockRenderingEvent extends Event implements \ArrayAccess
{
/**
*
* @var mixed[]
*/
protected $context;
/**
* The returned content of the event
*
* @var string
*/
protected $content = '';
public function __construct(array $context)
{
$this->context = $context;
}
/**
* add content to the event. This content will be printed in the
* layout which launched the event
*
* @param string $text
*/
public function addContent($text)
{
$this->content .= $text;
}
/**
* the content of the event
*
* @return string
*/
public function getContent()
{
return $this->content;
}
public function offsetExists($offset)
{
return isset($this->context[$offset]);
}
public function offsetGet($offset)
{
return $this->context[$offset];
}
public function offsetSet($offset, $value)
{
throw new \RuntimeException("The event context is read-only, you are not "
. "allowed to update it.");
}
public function offsetUnset($offset)
{
throw new \RuntimeException("The event context is read-only, you are not "
. "allowed to update it.");
}
}