Visualizzazione post con etichetta symfony. Mostra tutti i post
Visualizzazione post con etichetta symfony. Mostra tutti i post

mercoledì 12 novembre 2014

Upload con Symfony2 di file .docx e .odt

Se si cerca di effettuare l'ulpload di file .docx e .odt su Symfony2, potrebbero esserci degli errori per quanto riguarda la validazione.


     * @Assert\File(
     *     maxSize = "2M",
     *     mimeTypes = {"applicatipreblockquoon/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "application/vnd.oasis.opendocument.text"},
     *     maxSizeMessage = "The maxmimum allowed file size is 2MB.",
     *     mimeTypesMessage = "Only the filetypes .doc .docx .odt are allowed."
     * )


Cercando on line ho letto che questi formati vengono riconosciuti come file.zip. Non so se il motivo sia realmente questo, comunque la soluzione che ho trovato è di inserire come mime type mime_type_guessers.


quindi


     * @Assert\File(
     *     maxSize = "2M",
     *     mimeTypes = {"applicatipreblockquoon/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "application/vnd.oasis.opendocument.text", "mime_type_guessers"},
     *     maxSizeMessage = "The maxmimum allowed file size is 2MB.",
     *     mimeTypesMessage = "Only the filetypes .doc .docx .odt are allowed."
     * )


Se ci fosse una soluzione migliore, per favore fatemela sapere. Grazie

martedì 29 luglio 2014

Symfony2, aggiungere una funzione DQL per ottenere la differenza tra due date utilizzando il motore MySql.

Può essere utile calcolare la differenza tra due date  direttamente nelle nostre query SQL.

Utilizzando Symfony2 e Doctrine, e possibile aggiungere la funzione DQL in questo modo:

doctrine-project


Creiamo il file Acme/DemoBundle/DQL/DateDiff.php

  
<?php

namespace Acme\AdminBundle\DQL;

use Doctrine\ORM\Query\AST\Functions\FunctionNode;
use Doctrine\ORM\Query\Lexer;


/**
 * DateDiffFunction ::= "DATEDIFF" "(" ArithmeticPrimary "," ArithmeticPrimary ")"
 */
class DateDiff extends FunctionNode
{
    // (1)
    public $firstDateExpression = null;
    public $secondDateExpression = null;

    public function parse(\Doctrine\ORM\Query\Parser $parser)
    {
        $parser->match(Lexer::T_IDENTIFIER); // (2)
        $parser->match(Lexer::T_OPEN_PARENTHESIS); // (3)
        $this->firstDateExpression = $parser->ArithmeticPrimary(); // (4)
        $parser->match(Lexer::T_COMMA); // (5)
        $this->secondDateExpression = $parser->ArithmeticPrimary(); // (6)
        $parser->match(Lexer::T_CLOSE_PARENTHESIS); // (3)
    }

    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
    {
        return 'DATEDIFF(' .
            $this->firstDateExpression->dispatch($sqlWalker) . ', ' .
            $this->secondDateExpression->dispatch($sqlWalker) .
        ')'; // (7)
    }
}

A questo punto é necessario registrare la funzione nel file app/config/config.yml

    orm:
        / ... /
        dql:
            datetime_functions:
                datediff:     Acme\DemoBundle\DQL\DateDiff
A questo punto sarà possibile scrivere query del genere:
SELECT p FROM DoctrineExtensions\Query\BlogPost p WHERE DATEDIFF(CURRENT_TIME(), p.created) < 7


... o del genere ;) ...

  $repository = $this->getDoctrine()
      ->getRepository('AcmeDemoBundle:Ads');

  $query = $repository->createQueryBuilder('a')
      ->where('a.idUser = :idUser')
      ->andWhere('DATEDIFF(a.datejob, CURRENT_DATE()) >= 1')
      ->setParameter('idUser', $this->getUser()->getId())
      ->getQuery();

  $ads = $query->getResult();

venerdì 25 luglio 2014

Utilizzando FosUserBundle il ruolo ROLE_USER non viene salvato nel database

Può capitare di dover attribuire dei ruoli differenti per ogni utente in un progetto Symfony2.

Se si utilizza FosUserBundle, il ruolo ROLE_USER sarà attribuito di default a tutti gli utenti e non sarà possibile salvarlo nel database.

Se si scrive qualcosa del genere
$user->addRole('ROLE_USER');

Il risultato sarà quello di avere un array vuoto nel database.

{}

 A seconda delle proprie necessità converrà aggiungere un nuovo ruolo, qualcosa del genere

$user->addRole('ROLE_CLIENT');

 oppure lasciare il database vuoto, consapevoli del fatto che il ruolo ROLE_USER é stato comunque aggiunto.

mercoledì 23 luglio 2014

Soft delete con Symfony2

Può capitare di dover implementare un sistema di soft delete nella propria applicazione web.

Niente di più semplice con queste estensioni di doctrine.

Per installare il bundle basta seguire le istruzioni.

Una volta installato é necessario modificare in questo modo la configurazione di doctrine nel file # app/config/config.yml
# Doctrine Configuration
doctrine:
    dbal:
        driver:   "%database_driver%"
        host:     "%database_host%"
        port:     "%database_port%"
        dbname:   "%database_name%"
        user:     "%database_user%"
        password: "%database_password%"
        charset:  UTF8
    orm:
        auto_generate_proxy_classes: "%kernel.debug%"
        auto_mapping: true
        filters:
            softdeleteable:
                class: Gedmo\SoftDeleteable\Filter\SoftDeleteableFilter
                enabled: true

Solo le ultime 4 righe sono da aggiungere, le altre dovrebbero essere già presenti nel file di configurazione.


Sempre nel file # app/config/config.yml aggiungiamo le righe:

stof_doctrine_extensions:
    orm:
        default:
            softdeleteable: true

Ora non ci rimane che andare a modificare l'entity per la quale vogliamo utilizzare il soft delete.

Apriamo il file dell'entity, ad esempio # src/Acme/UserBundle/Entity/User.php.

Aggiungiamo prima della classe
use Gedmo\Mapping\Annotation as Gedmo;

La riga seguente invece va inserita tra i commenti, sempre prima della classe

 /*
 * @Gedmo\SoftDeleteable(fieldName="deletedAt")
 */

come ultima cosa aggiungiamo il campo che farà la differenza tra un record cancellato e uno ancora in uso.

    /**
     * @var \DateTime $deletedAt
     *
     * @ORM\Column(name="deleted_at", type="datetime", nullable=true)
     */
    private $deletedAt;


La classe dovrebbe essere più o meno così



namespace Acme\UserBundle\Entity;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Gedmo\Mapping\Annotation as Gedmo; 
/**
 * @Gedmo\SoftDeleteable(fieldName="deletedAt")
 * @ORM\Entity
 * @ORM\Table(name="fos_user")
 */
class User extends BaseUser
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;
    /**
     * @var \DateTime $deletedAt
     *
     * @ORM\Column(name="deleted_at", type="datetime", nullable=true)
     */
    private $deletedAt; 

    public function __construct()
    {
        parent::__construct();
        // your own logic
    }


     
Il sistema fa tutto da solo, non c'é bisogno di modificare nient'altro, né le chiamate per cancellare le entity ->remove($user) né le query per selezionare i dati. Tra l'altro, se sono presenti delle relazioni tra tabelle (scritte correttamente) e se le query sono scritte bene, viene aggiornato tutto automaticamente.

giovedì 10 luglio 2014

Recuperare variabili GET con twig

Ipotizziamo di dover recuperare una variabile inviata con tramite GET con Twig.
In realtà non si capisce perchè uno debba fare una cosa del genere, vista la potenza delle rotte di symfony, ma non si sa mai.

Quindi ipotizziamo un indirizzo del genere con tanto di variabile GET annessa.

www.miosito.com/pagina/?nomeVariabile=123

Per recuperare il valore della variabile con twig basterà

{{ app.request.query.get('nomeVariabile') }}


mercoledì 18 giugno 2014

Errore timezone Utilizzando MAMP

Qualche tempo fa mi é capitato di trovare questo strano errore aggiornando il mio progetto Symfony che girava su un MAC con MAMP.


[Symfony\Component\Debug\Exception\ContextErrorException]                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
  Warning: date_default_timezone_get(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /Applications/MAMP/htdocs/xxx/vendor/monolog/monolog/src/Monolog/Logger.php line 233

Ho controllato il file php.ini di riferimento in phpinfo(), ma risultava tutto corretto.
Quindi nel mio caso doveva essere

date.timezone = "Europe/London"

E così era.

Cercando on line ho scoperto che MAMP, non so bene perché fa riferimento ad altri file. Non sono un esperto di MAC o di MAMP, quindi non ho proprio idea del perché di questa roba.

Comunque sono dovuto entrare nella cartella /private e modificare il file php.ini.

Questo penso che sia fattibile solo da terminale.

Quindi

sudo nano /private/etc/php.ini 

Se il file php.ini non dovesse esistere, bisogna fare una copia del file php.ini.default e modificare quella.


sudo cp php.ini.default php.ini 

A questo punto non rimane che cercare la riga riguardante date.timezone, togliere il ';' da davanti e aggiungere  "Europe/London" o il corretto valore.

Se dovesse servire, ecco qui la lista dei corretti valori da inserire a seconda delle necessità.

martedì 27 maggio 2014

PDO Exception Symfony2

Può capitare di dover intercettare un'eccezione, ma se questa viene generata da PDO non viene riconosciuta.

Facendo una cosa del genere non si ottiene niente.

try {
      ...
$em->flush();
 } catch (Exception $e) {
     ...
 }



Per poter riconoscere l'eccezione é necessario cambiare Exception con \Exception.
PHP cerca di trovare \TuoNamespaceConController\Exception invece di \Exception.

Quindi
try {
      ...
$em->flush();
 } catch (\Exception $e) {
     ...
 }

giovedì 20 febbraio 2014

Visualizzare documenti PDF con PHP e Symfony2

Come fare per visualizzare un documento pdf nel proprio sito senza dover per forza fare il download? Ci aiuta una libreria scritta in HTML5 e Javascript, sviluppata da Mozilla.

PDF.js

Demo

Per utilizzarla con Symfony2 abbiamo anche un bundle che ci semplifica la vita.

SalvaPdfJsBundle

Nella pagina è presente tutta la documentazione necessaria per utilizzarlo.



Ho trovato anche questo, dovrebbe essere un'alternativa, però non l'ho testato.

Viewer.JS

Discussione su stackoverflow.com

martedì 17 dicembre 2013

Lista timezones per settare il file php.ini

Quando si programma in php, spesso è necessario modificare il file php.ini. Quando si programma con Symfony è obbligatorio settare dei parametri nel file php.ini. Uno di questi è il timezone. Ecco la lista di timezones supportate:

LISTA

venerdì 13 dicembre 2013

Creare form dinamicamente con Symfony2.3

Creare un form dinamicamente con symfony due è molto più semplice di quanto non si pensi.
Ecco un esempio di form creato in funzione di entity estratte dal database.
Ipotizzando di avere un database con delle voci e voler creare un checkbox distinto per ogni voce.

        $element = $this->getDoctrine()
            ->getRepository('AcmeDemoBundle:Elements')
            ->find($id);
           
        $formBuilder = $this->createFormBuilder();
       
        for($i = 0; $i < count($element); $i++){
                $formBuilder->add($element[$i]->getId(), 'checkbox', array(
                'label'     => $element[$i]->getId(),
                'required'  => false,
            ));
        }
         
        $formBuilder->add('save', 'submit');
        $form = $formBuilder->getForm();
       
        return $this->render('AcmeDemoBundle:Demo:index.html.twig', array(
            'form' => $form->createView()
        ));   
L'esempio fatto è abbastanza inutile visto che converrebbe fare in manierà più pulita così:
->add('element', 'entity', array('label' => 'Element', 
 'class' => 'AcmeDemoBundle:Elements',
 'property' => 'name',
 'required'    => true,
 'multiple' => true,
 'expanded' => true    
))
Oppure ancora
  $repository = $this->getDoctrine()->getRepository('AcmeUserBundle:User');

  $query = $repository->createQueryBuilder('p')
         ->where('p.roles LIKE :roles')
         ->setParameter('roles', '%"ROLE_ADMIN"%')
  ->getQuery();

  $element = $query->getResult();

  $formBuilder = $this->createFormBuilder();

  $users = array();

  for($i = 0; $i < count($element); $i++){
   $users = array($element[$i]->getId() => $element[$i]->getUsername());
  }

  $formBuilder->add('User', 'choice', array(
      'choices'   => $users,
      'required'  => false,
  ));

  $formBuilder->add('save', 'submit');
  $form = $formBuilder->getForm();



P.S.
Non so bene perché, ma facendo copia incolla di questo codice sul mac, utilizzando Sublime Text come editor, tutti gli spazi bianchi risultano errori, quindi attenzione, gli "errori fantasma" che verranno segnalati sono solo gli spazi che avete copiato. Toglieteli per risolvere il problema.

domenica 1 dicembre 2013

Ottenere informazioni utente fosUserBundle Symfony2

Per recuperare I dati dell'utente nel controller è necessario utilizzare l'oggetto
$this->getUser()
Quindi per recuperare, ad esempio, l'id dell'utente bisogna utilizzare il metodo ->getId quindi:
$this->getUser()->getId()
Per fare la stessa cosa sul template, quindi utilizzando twig, bisogna fare la stessa cosa, quindi per far spampare l'username dell'utente:
{{ app.user.username }}
E' possibile anche controllare se l'utente è loggato:
{% if is_granted("ROLE") %}
    Hi {{ app.user.username }}
{% endif %}
Ovviamente è necessario scrivere al posto di ROLE il reale ruolo dell'utente, quello che si è scritto nel file di configurazione, ad esempio ROLE_USER o ROLE_ADMIN.