Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
 
3
/*
4
 * This file is part of the symfony package.
5
 * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
 
11
/**
12
 * Adds support for symfony's {@link sfMixer} behaviors.
13
 *
14
 * @package     sfPropelPlugin
15
 * @subpackage  behavior
16
 * @author      Kris Wallsmith <kris.wallsmith@symfony-project.com>
17
 * @version     SVN: $Id: SfPropelBehaviorSymfonyBehaviors.php 28958 2010-04-01 13:56:17Z fabien $
18
 */
19
class SfPropelBehaviorSymfonyBehaviors extends SfPropelBehaviorBase
20
{
21
  public function preDelete()
22
  {
23
    if ($this->isDisabled())
24
    {
25
      return;
26
    }
27
 
28
    return <<<EOF
29
foreach (sfMixer::getCallables('Base{$this->getTable()->getPhpName()}:delete:pre') as \$callable)
30
{
31
  if (call_user_func(\$callable, \$this, \$con))
32
  {
33
    \$con->commit();
34
 
35
    return;
36
  }
37
}
38
 
39
EOF;
40
  }
41
 
42
  public function postDelete()
43
  {
44
    if ($this->isDisabled())
45
    {
46
      return;
47
    }
48
 
49
    return <<<EOF
50
foreach (sfMixer::getCallables('Base{$this->getTable()->getPhpName()}:delete:post') as \$callable)
51
{
52
  call_user_func(\$callable, \$this, \$con);
53
}
54
 
55
EOF;
56
  }
57
 
58
  public function preSave()
59
  {
60
    if ($this->isDisabled())
61
    {
62
      return;
63
    }
64
 
65
    return <<<EOF
66
foreach (sfMixer::getCallables('Base{$this->getTable()->getPhpName()}:save:pre') as \$callable)
67
{
68
  if (is_integer(\$affectedRows = call_user_func(\$callable, \$this, \$con)))
69
  {
70
    \$con->commit();
71
 
72
    return \$affectedRows;
73
  }
74
}
75
 
76
EOF;
77
  }
78
 
79
  public function postSave()
80
  {
81
    if ($this->isDisabled())
82
    {
83
      return;
84
    }
85
 
86
    return <<<EOF
87
foreach (sfMixer::getCallables('Base{$this->getTable()->getPhpName()}:save:post') as \$callable)
88
{
89
  call_user_func(\$callable, \$this, \$con, \$affectedRows);
90
}
91
 
92
EOF;
93
  }
94
 
95
  public function objectMethods()
96
  {
97
    if ($this->isDisabled())
98
    {
99
      return;
100
    }
101
 
102
    return <<<EOF
103
 
104
/**
105
 * Calls methods defined via {@link sfMixer}.
106
 */
107
public function __call(\$method, \$arguments)
108
{
109
  if (!\$callable = sfMixer::getCallable('Base{$this->getTable()->getPhpName()}:'.\$method))
110
  {
111
    throw new sfException(sprintf('Call to undefined method Base{$this->getTable()->getPhpName()}::%s', \$method));
112
  }
113
 
114
  array_unshift(\$arguments, \$this);
115
 
116
  return call_user_func_array(\$callable, \$arguments);
117
}
118
 
119
EOF;
120
  }
121
 
122
  public function staticMethods()
123
  {
124
    if ($this->isDisabled())
125
    {
126
      return;
127
    }
128
 
129
    return <<<EOF
130
 
131
/**
132
 * Returns the name of the hook to call from inside the supplied method.
133
 *
134
 * @param string \$method The calling method
135
 *
136
 * @return string A hook name for {@link sfMixer}
137
 *
138
 * @throws LogicException If the method name is not recognized
139
 */
140
static private function getMixerPreSelectHook(\$method)
141
{
142
  if (preg_match('/^do(Select|Count)(Join(All(Except)?)?|Stmt)?/', \$method, \$match))
143
  {
144
    return sprintf('Base{$this->getTable()->getPhpName()}Peer:%s:%1\$s', 'Count' == \$match[1] ? 'doCount' : \$match[0]);
145
  }
146
 
147
  throw new LogicException(sprintf('Unrecognized function "%s"', \$method));
148
}
149
 
150
EOF;
151
  }
152
 
153
  public function preSelect()
154
  {
155
    if ($this->isDisabled())
156
    {
157
      return;
158
    }
159
 
160
    return <<<EOF
161
foreach (sfMixer::getCallables(self::getMixerPreSelectHook(__FUNCTION__)) as \$sf_hook)
162
{
163
  call_user_func(\$sf_hook, 'Base{$this->getTable()->getPhpName()}Peer', \$criteria, \$con);
164
}
165
 
166
EOF;
167
  }
168
 
169
  public function objectFilter(& $script)
170
  {
171
    if ($this->isDisabled())
172
    {
173
      return;
174
    }
175
 
176
    if ($this->getTable()->getAttribute('behaviors'))
177
    {
178
      $script .= $this->getBehaviorsInclude();
179
    }
180
  }
181
 
182
  public function peerFilter(& $script)
183
  {
184
    if ($this->isDisabled())
185
    {
186
      return;
187
    }
188
 
189
    $doInsertPre = <<<EOF
190
// symfony_behaviors behavior
191
    foreach (sfMixer::getCallables('Base{$this->getTable()->getPhpName()}Peer:doInsert:pre') as \$sf_hook)
192
    {
193
      if (false !== \$sf_hook_retval = call_user_func(\$sf_hook, 'Base{$this->getTable()->getPhpName()}Peer', \$values, \$con))
194
      {
195
        return \$sf_hook_retval;
196
      }
197
    }
198
 
199
EOF;
200
    $doUpdatePre = <<<EOF
201
// symfony_behaviors behavior
202
    foreach (sfMixer::getCallables('Base{$this->getTable()->getPhpName()}Peer:doUpdate:pre') as \$sf_hook)
203
    {
204
      if (false !== \$sf_hook_retval = call_user_func(\$sf_hook, 'Base{$this->getTable()->getPhpName()}Peer', \$values, \$con))
205
      {
206
        return \$sf_hook_retval;
207
      }
208
    }
209
 
210
EOF;
211
 
212
    // add doInsert and doUpdate hooks
213
    $class = new sfClassManipulator($script);
214
    $class->filterMethod('doInsert', array($this, 'filterDoInsert'));
215
    $class->wrapMethod('doInsert', $doInsertPre);
216
    $class->filterMethod('doUpdate', array($this, 'filterDoUpdate'));
217
    $class->wrapMethod('doUpdate', $doUpdatePre);
218
 
219
    $script = $class->getCode();
220
 
221
    // add symfony behavior configuration file
222
    if ($this->createBehaviorsFile())
223
    {
224
      $script .= $this->getBehaviorsInclude();
225
    }
226
  }
227
 
228
  /**
229
   * Filters the generated doInsert method.
230
   *
231
   * @param string $line
232
   *
233
   * @return string
234
   */
235
  public function filterDoInsert($line)
236
  {
237
    if (false !== strpos($line, 'return'))
238
    {
239
      $doInsertPost = <<<EOF
240
    // symfony_behaviors behavior
241
    foreach (sfMixer::getCallables('Base{$this->getTable()->getPhpName()}Peer:doInsert:post') as \$sf_hook)
242
    {
243
      call_user_func(\$sf_hook, 'Base{$this->getTable()->getPhpName()}Peer', \$values, \$con, \$pk);
244
    }
245
 
246
 
247
EOF;
248
 
249
      $line = $doInsertPost.$line;
250
    }
251
 
252
    return $line;
253
  }
254
 
255
  /**
256
   * Filters the generated doUpdate method.
257
   *
258
   * @param string $line
259
   *
260
   * @return string
261
   */
262
  public function filterDoUpdate($line)
263
  {
264
    if (false !== strpos($line, 'return'))
265
    {
266
      $replace = str_replace('return', '$ret =', $line);
267
      $doUpdatePost = <<<EOF
268
 
269
    // symfony_behaviors behavior
270
    foreach (sfMixer::getCallables('Base{$this->getTable()->getPhpName()}Peer:doUpdate:post') as \$sf_hook)
271
    {
272
      call_user_func(\$sf_hook, 'Base{$this->getTable()->getPhpName()}Peer', \$values, \$con, \$ret);
273
    }
274
 
275
    return \$ret;
276
 
277
EOF;
278
 
279
      $line = $replace.$doUpdatePost;
280
    }
281
 
282
    return $line;
283
  }
284
 
285
  /**
286
   * Creates the current model's behaviors configuration file.
287
   *
288
   * Any existing behaviors file will be either deleted or overwritten.
289
   *
290
   * @return boolean Returns true if the model has behaviors
291
   */
292
  protected function createBehaviorsFile()
293
  {
294
    $file = $this->getBehaviorsFilePath(true);
295
 
296
    if (file_exists($file))
297
    {
298
      unlink($file);
299
    }
300
 
301
    if ($behaviors = $this->getTable()->getAttribute('behaviors'))
302
    {
303
      $code = <<<EOF
304
<?php
305
 
306
sfPropelBehavior::add('{$this->getTable()->getPhpName()}', %s);
307
 
308
EOF;
309
 
310
      file_put_contents($file, sprintf($code, var_export(unserialize($behaviors), true)));
311
      return true;
312
    }
313
  }
314
 
315
  /**
316
   * Returns PHP code for including the current model's behaviors configuration file.
317
   *
318
   * @return string
319
   */
320
  protected function getBehaviorsInclude()
321
  {
322
    return <<<EOF
323
 
324
// symfony_behaviors behavior
325
include_once '{$this->getBehaviorsFilePath()}';
326
 
327
EOF;
328
  }
329
 
330
  /**
331
   * Returns the path to the current model's behaviors configuration file.
332
   *
333
   * @param boolean $absolute
334
   *
335
   * @return string
336
   */
337
  protected function getBehaviorsFilePath($absolute = false)
338
  {
339
    $base = $absolute ? sfConfig::get('sf_root_dir').DIRECTORY_SEPARATOR : '';
340
    return $base.ClassTools::getFilePath($this->getTable()->getPackage().'.om', sprintf('Base%sBehaviors', $this->getTable()->getPhpName()));
341
  }
342
}