A typical Developer Blog
by Gordon Franke
Icon

Bash Skript zum Erstellen eines Symfony Projekts mit sfDoctrinePlugin, sfDoctrineGuardPlugin und sfDoctrineGuardExtraPlugin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
#!/bin/bash
 
# config
PROJECTNAME=TEST;
APPNAME=frontend;
AUTHORNAME=gfranke;
CSRFSECRET=UniqueSecret;
 
#DBDSN="sqlite:%SF_DATA_DIR%/sandbox.db";
DBDSN="mysql:host=localhost;dbname=symfony_build_with_guard";
DBUSER=root;
DBPASS="";
 
SYMFONYTAG=RELEASE_1_2_4;
 
# sfGaurdExtraPlugin don't work with propel
ORM=doctrine;
 
 
# remove existing files
rm apps/ web/ plugins/ lib/ log/ config/ cache/ data/ doc/ symfony test/ vendor/symfony_plugins/ -Rf;
 
# make vendor dir
if ! [ -d vendor ]; then
  mkdir vendor;
fi
 
# make symfony vendor dir
if ! [ -d vendor/symfony ]; then
  mkdir vendor/symfony;
fi
 
# get symfony
if ! [ -d vendor/symfony/${SYMFONYTAG}_lib ]; then
  svn export http://svn.symfony-project.com/tags/${SYMFONYTAG}/lib vendor/symfony/${SYMFONYTAG}_lib;
fi
if ! [ -d vendor/symfony/${SYMFONYTAG}_data ]; then
  svn export http://svn.symfony-project.com/tags/${SYMFONYTAG}/data vendor/symfony/${SYMFONYTAG}_data;
fi
 
# make current links for fast switch
if ! [ -L vendor/symfony/current_lib ]; then
  ln -s RELEASE_1_2_4_lib vendor/symfony/current_lib;
fi
if ! [ -L vendor/symfony/current_data ]; then
  ln -s RELEASE_1_2_4_data vendor/symfony/current_data;
fi
 
# only for build
if ! [ -L vendor/symfony/lib ]; then
  ln -s current_lib vendor/symfony/lib;
fi
if ! [ -L vendor/symfony/data ]; then
  ln -s current_data vendor/symfony/data;
fi
 
# init symfony
php vendor/symfony/data/bin/symfony generate:project $PROJECTNAME;
 
# correct symfony lib
sed "3d"  config/ProjectConfiguration.class.php2;
sed "3irequire_once dirname(__FILE__).'/../vendor/symfony/current_lib/autoload/sfCoreAutoload.class.php';"  config/ProjectConfiguration.class.php;
 
# remove build temp dirs
rm vendor/symfony/lib vendor/symfony/data;
 
# set author name
./symfony configure:author $AUTHORNAME;
 
# generate app
./symfony generate:app --escaping-strategy=on --csrf-secret=$CSRFSECRET $APPNAME;
 
# get plugins
mkdir vendor/symfony_plugins;
if [ "$ORM" = "propel" ]; then
  SVNVERSION=`svn info http://svn.symfony-project.com/plugins/sfGuardPlugin/branches/1.2/ | sed '8s/[^0-9]*//' | sed '1,7d' | sed '2,4d'`;
  svn export http://svn.symfony-project.com/plugins/sfGuardPlugin/branches/1.2/ vendor/symfony_plugins/sfGuardPlugin;
 
  ln -s sfGuardPlugin_$SVNVERSION vendor/symfony_plugins/sfGuardPlugin_current;
  ln -s ../vendor/symfony_plugins/sfGuardPlugin_current plugins/sfGuardPlugin;
 
  SVNVERSION=`svn info http://svn.symfony-project.com/plugins/sfGuardExtraPlugin/branches/1.2/ | sed '8s/[^0-9]*//' | sed '1,7d' | sed '2,4d'`;
  svn export http://svn.symfony-project.com/plugins/sfGuardExtraPlugin/branches/1.2/ vendor/symfony_plugins/sfGuardExtraPlugin;
 
  ln -s sfGuardExtraPlugin_$SVNVERSION vendor/symfony_plugins/sfGuardExtraPlugin_current;
  ln -s ../vendor/symfony_plugins/sfGuardExtraPlugin_current plugins/sfGuardExtraPlugin;
 
  # database config
  ./symfony configure:database "sqlite:%SF_DATA_DIR%/sandbox.db"
else
  sed '11s/sfDoctrinePlugin/sfPropelPlugin/'  config/ProjectConfiguration.class.php2;
  mv config/ProjectConfiguration.class.php2 config/ProjectConfiguration.class.php;
 
  SVNVERSION=`svn info http://svn.symfony-project.com/plugins/sfDoctrineGuardPlugin/branches/1.2/ | sed '8s/[^0-9]*//' | sed '1,7d' | sed '2,4d'`;
  svn export http://svn.symfony-project.com/plugins/sfDoctrineGuardPlugin/branches/1.2/ vendor/symfony_plugins/sfDoctrineGuardPlugin_$SVNVERSION;
 
  ln -s sfDoctrineGuardPlugin_$SVNVERSION vendor/symfony_plugins/sfDoctrineGuardPlugin_current;
  ln -s ../vendor/symfony_plugins/sfDoctrineGuardPlugin_current plugins/sfDoctrineGuardPlugin;
 
  SVNVERSION=`svn info http://svn.symfony-project.com/plugins/sfDoctrineGuardExtraPlugin/branches/1.2/ | sed '8s/[^0-9]*//' | sed '1,7d' | sed '2,4d'`;
  svn export http://svn.symfony-project.com/plugins/sfDoctrineGuardExtraPlugin/branches/1.2/ vendor/symfony_plugins/sfDoctrineGuardExtraPlugin_$SVNVERSION;
 
  ln -s sfDoctrineGuardExtraPlugin_$SVNVERSION vendor/symfony_plugins/sfDoctrineGuardExtraPlugin_current;
  ln -s ../vendor/symfony_plugins/sfDoctrineGuardExtraPlugin_current plugins/sfDoctrineGuardExtraPlugin;
 
  # database config
  ./symfony configure:database --name=doctrine --class=sfDoctrineDatabase $DBDSN $DBUSER $DBPASS
 
  # remove propel connection
  sed '2,6s/propel/doctrine/'  config/databases.yml2;
  mv config/databases.yml2 config/databases.yml;
fi
 
# enabled modules and change login module and action
sed "31i    # Activated modules from plugins or from the symfony coren    enabled_modules: [default, sfGuardAuth, sfGuardRegister, sfGuardForgotPassword]n"  apps/frontend/config/settings.yml2;
mv apps/frontend/config/settings.yml2 apps/frontend/config/settings.yml;
 
# deactivate guard routes
sed "2d"  apps/frontend/config/app.yml2;
echo "all:n  sf_guard_plugin:n    routes_register: falsen" >> apps/frontend/config/app.yml2;
mv apps/frontend/config/app.yml2 apps/frontend/config/app.yml;
 
# insert guard routes
sed "6isf_guard_signin:n  url:   /loginn  param: { module: sfGuardAuth, action: signin }nnsf_guard_signout:n  url:   /logoutn  param: { module: sfGuardAuth, action: signout }n"  apps/frontend/config/routing.yml2;
mv apps/frontend/config/routing.yml2 apps/frontend/config/routing.yml;
 
# create db file
touch data/sandbox.db
chmod 777 data
chmod 777 data/sandbox.db
 
# extends sfGuardSecurityUser
sed '3s/sfBasicSecurityUser/sfGuardSecurityUser/'  apps/frontend/lib/myUser.class.php2;
mv apps/frontend/lib/myUser.class.php2 apps/frontend/lib/myUser.class.php;
 
# clear cache
./symfony cc
 
# fix permissions
./symfony fix-perms
 
# build db model filter and forms
if [ "$ORM" = "propel" ]; then
  ./symfony propel:build-all --no-confirmation
else
  ./symfony doctrine:build-model
 
  echo "hasColumn('email', 'string', 80, array('notnull' => true, 'unique' => true));
  }
 
  public function getEmailAddress()
  {
    return $this->email;
  }
 
  public function setEmailAddress($email)
  {
    $this->email = $email;
  }
}" > lib/model/doctrine/sfDoctrineGuardPlugin/sfGuardUser.class.php;
 
  echo "from('sfGuardUser u')->where( '(u.username = ? OR u.email = ?) AND u.is_active = ?', array( $usernameOrEmail, $usernameOrEmail, $isActive ) )->execute()->getFirst();
  }
}
" > lib/model/doctrine/sfDoctrineGuardPlugin/sfGuardUserTable.class.php;
 
  # schema to inndb
  echo "---
options:
  type: INNODB
"  > config/doctrine/schema.yml
 
  # cleanup
  rm config/schema.yml config/propel.ini
 
  ./symfony doctrine:build-all-reload --no-confirmation
fi
 
# publish assets don't use publish-assets symlink must go to current link
rm web/sfPropelPlugin web/sfProtoculousPlugin;
ln -s ../vendor/symfony/current_data/web/sf/ web/sf;
ln -s ../vendor/symfony/current_lib/plugins/sfProtoculousPlugin/web web/sfProtoculousPlugin;
if [ "$ORM" = "propel" ]; then
  ln -s ../vendor/symfony/current_lib/plugins/sfPropelPlugin/web web/sfPropelPlugin;
else
  ln -s ../vendor/symfony/current_lib/plugins/sfDoctrinePlugin/web web/sfDoctrinePlugin;
fi
 
# clear cache
./symfony cc

Wie kann ich alle Formular Pflichtfelder mit einem * kennzeichnen?

Erstelle die Datei lib/gfFormHerlp.class.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?php
 
/**
 * Some usefull form helper
 *
 * @package    symfony
 * @subpackage helper
 * @author     Gordon Franke <gfranke@nevalon.de>
 * @link       http://www.nevalon.de
 */
class gfFormHelper
{
  /**
   * Add * to required field labels
   *
   * @param sfForm $form
   * @param string $symbol
   * @param string $title
   *
   * @return void
   */
  public static function addRequiredToLabel(sfForm $form, $symbol = '*', $title = 'This field is mandatory.')
  {
    $widgetSchema = $form->getWidgetSchema();
    $validatorSchema = $form->getValidatorSchema();
 
    foreach($form->getFormFieldSchema()->getWidget()->getFields() as $key => $object)
    {
      $label = $form->getFormFieldSchema()->offsetGet($key)->renderLabelName();
      if(isset($validatorSchema[$key]) and $validatorSchema[$key]->getOption('required') == true) {
        $label .= '<sup title="' . $widgetSchema->getFormFormatter()->translate($title) . '">' . $symbol . '</sup>';
      }
      $widgetSchema->setLabel($key, $label);
    }
  }
}

Füge folgendes am ende deiner Formular in der setup oder besser wenn du Unterformulare hast in der configure Methode ein

1
gfFormHelper::addRequiredToLabel($this);

Wie kann ich meine eigenen User Funktionen Unit testen?

Benutze dies in deinem Testcode um das User Objekt zu erstellen

1
2
3
4
5
6
7
8
$_SERVER['session_id'] = 'test';
 
$dispatcher = new sfEventDispatcher();
$sessionPath = sfToolkit::getTmpDir().'/sessions_'.rand(11111, 99999);
$storage = new sfSessionTestStorage(array('session_path' => $sessionPath));
 
$myUser = new myUser($dispatcher, $storage);
$myUser->setAttribute('user_id', 1, 'sfGuardSecurityUser');

Wie erstelle ich ein Feed für mein Symfony Projekt in drei Schritten?

Erster Schritt zend framework implementieren

[cref 30 Wie kann ich Zend Framework Komponenten in meinem Symfony Projekt nutzen?]

Zweiter Schritt feed Modul erstellen und template Ordner löschen

./symfony generate:module frontend feed
rm apps/frontend/modules/feed/templates/ -Rf

Dritter Schritt index Funktion ersetzen

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public function executeIndex(sfWebRequest $request)
{
  ProjectConfiguration::registerZend();
 
  $feedArray = array(
    'title' => ...,
    'link' => $this->generateUrl('default_index', array('module' => 'feed')),
    'description' => ..,
    'language' => ...,
    'charset' => sfConfig::get('sf_charset'),
    'pubDate' => time(),
    'entries' => array()
  );
 
  /* get the data from the db or outher source */
 
  foreach($articles as $article)
  {
    $feedArray['entries'][] = array(
      'title' => $article['title'],
      'link' => $this->generateUrl('article_detail', $article),
      'guid' => $article['id'],
      'description' => $article['description']
    );
  }
 
  $feed = Zend_Feed::importArray($feedArray, 'rss');
  $feed->send();
 
  throw new sfStopException();
}

das wars für weitere Information siehe

Zend_Feed

Wie kann mir Symfony eine email schicken, wenn ein log Mitteilung erstellt wird?

UPDATE: Ich habe die Klasse aktualisiert und einen neuen Parameter hinzugefügt include_level

Aktiviere das logging für die prod Umgebung in der settings.yml

prod:
  .settings:
    logging_enabled:        on

füge dies zu deiner factories.yml hinzu

prod:
  logger:
    param:
      level: debug
      loggers:
        sf_web_debug:
          class: sfNoLogger
        sf_file_debug:
          param:
            level: warning
        sc_mail:
          class: gfMailLogger
          param:
            level: warning
            include_level: debug
            emails: ["test@test.de"]

erstelle gfMailLogger.class.php in deinem lib Ordner

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
<?php
 
/**
 * gfMailLogger logs messages and send it via email.
 *
 * @package    symfony
 * @subpackage log
 * @author     Gordon Franke <gfranke@nevalon.de>
 * @link       http://www.nevalon.de
 */
class gfMailLogger extends sfLogger
{
  protected
    $emails     = array(),
    $subject,
    $body,
    $include_level,
    $log = false,
    $type       = 'symfony',
    $format     = '%time% %type% [%priority%] %message%%EOL%',
    $timeFormat = '%b %d %H:%M:%S';
 
  /**
   * Initializes this logger.
   *
   * Available options:
   *
   * - emails:        The emails to be send the log messages
   * - subject:       The subject for the email
   * - include_level: Use this to get more detailed information
   * - format:        The log line format (default to %time% %type% [%priority%] %message%%EOL%)
   * - time_format:   The log time strftime format (default to %b %d %H:%M:%S)
   *
   * @param  sfEventDispatcher $dispatcher  A sfEventDispatcher instance
   * @param  array             $options     An array of options.
   *
   * @return Boolean      true, if initialization completes successfully, otherwise false.
   */
  public function initialize(sfEventDispatcher $dispatcher, $options = array())
  {
    if (!isset($options['emails']))
    {
      throw new sfConfigurationException('You must provide a "emails" parameter for this logger.');
    }
    $this->emails = $options['emails'];
 
    if (isset($options['format']))
    {
      $this->format = $options['format'];
    }
 
    if (isset($options['time_format']))
    {
      $this->timeFormat = $options['time_format'];
    }
 
    if (isset($options['type']))
    {
      $this->type = $options['type'];
    }
 
    if (isset($options['subject']))
    {
      $this->subject = $options['subject'];
    }
    else
    {
      $this->subject = sfConfig::get('sf_app') . ':: Log';
    }
 
    parent::initialize($dispatcher, $options);
 
    if (isset($options['include_level']))
    {
      if (!is_int($options['include_level']))
      {
        $options['include_level'] = constant('sfLogger::'.strtoupper($options['include_level']));
      }
 
      $this->include_level = $options['include_level'];
    }
    else
    {
      $this->include_level = $this->getLogLevel();
    }
  }
 
  /**
   * Logs a message.
   *
   * @param string $message   Message
   * @param string $priority  Message priority
   */
  public function log($message, $priority = self::INFO)
  {
    if ($this->include_level < $priority)
    {
      return false;
    }
    if($this->getLogLevel() >= $priority)
    {
      $this->log = true;
    }
 
    return $this->doLog($message, $priority);
  }
 
  /**
   * Logs a message.
   *
   * @param string $message   Message
   * @param string $priority  Message priority
   */
  protected function doLog($message, $priority)
  {
    $this->body .= strtr($this->format, array(
      '%type%'     => $this->type,
      '%message%'  => $message,
      '%time%'     => strftime($this->timeFormat),
      '%priority%' => $this->getPriority($priority),
      '%EOL%'      => PHP_EOL,
    ));
  }
 
  /**
   * Returns the priority string to use in log messages.
   *
   * @param  string $priority The priority constant
   *
   * @return string The priority to use in log messages
   */
  protected function getPriority($priority)
  {
    return sfLogger::getPriorityName($priority);
  }
 
  /**
   * Executes the shutdown method.
   */
  public function shutdown()
  {
    if($this->log)
    {
      foreach($this->emails as $email)
      {
        mail($email, $this->subject, $this->body);
      }
    }
  }
}

Wie kann ich Werte nach dem Abschicken eines Formulars hinzufügen?

Ich möchte die user id des aktuell eingelogten zum formular hinzufügen. Ich könnte ein hidden feld benutzen, aber das ist nicht sicher. Also rufe ich die updateObject($values) methode zwischen isValid() und save() auf.

1
2
3
4
5
6
7
8
9
10
11
protected function processForm(sfWebRequest $request, sfForm $form)
{
  $form->bind($request->getParameter($form->getName()));
  if ($form->isValid())
  {
    $form->updateObject(array('user_id' => $this->getUser()->getAttribute('user_id', null, 'sfGuardSecurityUser')));
    $article = $form->save();
 
    $this->redirect($this->generateUrl('article_detail', $article));
  }
}

Wie kann ich Zend Framework Komponenten in meinem Symfony Projekt nutzen?

füge folgenden Code in deine config/ProjectConfiguration.class.php hinzu

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
static protected $zendLoaded = false;
 
static public function registerZend()
{
  if (self::$zendLoaded)
  {
    return;
  }
 
  set_include_path(sfConfig::get('sf_root_dir').'/vendor/zend_framework/current'.PATH_SEPARATOR.get_include_path());
 
  require_once sfConfig::get('sf_root_dir').'/vendor/zend_framework/current/Zend/Loader.php';
 
  Zend_Loader::registerAutoload();
 
  self::$zendLoaded = true;
}

rufe die statische Funktion einmal auf bevor du eine Zend Framework komponente benutzt

ProjectConfiguration::registerZend();

Wie kann ich dynamische Urls mit Symfony erstellen?

Ich habe eine einfache article Tabelle mit einer id und einer title Spalte.
Ich möchte urls wie diese generieren.

/my-title-4
/:title-:id

Außerdem soll automatisch zur aktuellen url umgeleitet werden wenn sich der title ändert.
Read the rest of this entry »