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) 2004-2006 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
 * sfMixer implements mixins and hooks.
13
 *
14
 * @package    symfony
15
 * @subpackage propel
16
 * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
17
 * @version    SVN: $Id: sfMixer.class.php 11108 2008-08-25 11:00:07Z Kris.Wallsmith $
18
 */
19
class sfMixer
20
{
21
  static protected
22
    $mixins          = array(),
23
    $mixinParameters = array(),
24
    $mixinInstances  = array();
25
 
26
  static public function register($name, $callable)
27
  {
28
    $lazy = false;
29
 
30
    if (is_array($callable))
31
    {
32
      $mixinClass = $callable[0];
33
      $mixinMethod = $callable[1];
34
      if (!is_object($mixinClass))
35
      {
36
        $rc = new ReflectionClass($mixinClass);
37
        $rm = $rc->getMethod($mixinMethod);
38
        if (!$rm->isStatic())
39
        {
40
          $lazy = true;
41
        }
42
      }
43
    }
44
    else
45
    {
46
      $mixinMethod = $callable;
47
    }
48
 
49
    $tmp = explode(':', $name);
50
    $class = $tmp[0];
51
 
52
    // do we have a method name
53
    if (isset($tmp[1]))
54
    {
55
      $method = $tmp[1];
56
 
57
      // do we have a hook name
58
      if (isset($tmp[2]))
59
      {
60
        $hook = $tmp[2];
61
      }
62
      else
63
      {
64
        $hook = $method;
65
        $name .= ':'.$hook;
66
      }
67
    }
68
    else
69
    {
70
      // this will be called with __call
71
      $method = $mixinMethod;
72
      $name = $class.':'.$method;
73
      $hook = '';
74
    }
75
 
76
    // we cannot register 2 new methods with the same name
77
    if (!$hook && isset(self::$mixins[$name]))
78
    {
79
      throw new Exception(sprintf('The class "%s" has already a mixin for method "%s".', $class, $mixinMethod));
80
    }
81
 
82
    // register mixin
83
    if (!isset(self::$mixins[$name]))
84
    {
85
      self::$mixins[$name] = array();
86
    }
87
 
88
    if (!isset(self::$mixinParameters[$name]))
89
    {
90
      self::$mixinParameters[$name] = array();
91
    }
92
 
93
    self::$mixins[$name][] = $callable;
94
    self::$mixinParameters[$name][] = array(
95
      'lazy'     => $lazy,
96
      'class'    => $class,
97
      'method'   => $method,
98
      'hook'     => $hook,
99
    );
100
  }
101
 
102
  static public function getMixinInstance($name)
103
  {
104
    if (!isset(self::$mixins[$name]))
105
    {
106
      return;
107
    }
108
 
109
    foreach (self::$mixins[$name] as $i => $mixin)
110
    {
111
      if (!self::$mixinParameters[$name][$i]['lazy'])
112
      {
113
        continue;
114
      }
115
 
116
      $class = $mixin[0];
117
      if (!isset(self::$mixinInstances[$class]))
118
      {
119
        self::$mixinInstances[$class] = new $class();
120
        if (method_exists(self::$mixinInstances[$class], 'initialize'))
121
        {
122
          self::$mixinInstances[$class]->initialize();
123
        }
124
      }
125
 
126
      self::$mixinParameters[$name][$i]['lazy'] = false;
127
      self::$mixins[$name][$i][0] = self::$mixinInstances[$class];
128
    }
129
  }
130
 
131
  static public function getCallables($name)
132
  {
133
    self::getMixinInstance($name);
134
 
135
    return isset(self::$mixins[$name]) ? self::$mixins[$name] : array();
136
  }
137
 
138
  static public function getCallable($name)
139
  {
140
    self::getMixinInstance($name);
141
 
142
    return isset(self::$mixins[$name]) ? self::$mixins[$name][0] : null;
143
  }
144
 
145
  static public function callMixins($hookName = null, $moreParams = array())
146
  {
147
    $traces = debug_backtrace();
148
    $function = $traces[1]['function'];
149
    $parameters = $traces[1]['args'];
150
    $class = $traces[1]['class'];
151
    $type = $traces[1]['type'];
152
    if ('__call' == $function)
153
    {
154
      $method     = $parameters[0];
155
      $parameters = $parameters[1];
156
    }
157
    else
158
    {
159
      $method = $function;
160
    }
161
 
162
    if ('->' == $type)
163
    {
164
      array_unshift($parameters, $traces[1]['object']);
165
    }
166
    else
167
    {
168
      array_unshift($parameters, $class);
169
    }
170
 
171
    // add more parameters
172
    $parameters = array_merge($parameters, (array) $moreParams);
173
 
174
    if ('__call' == $function)
175
    {
176
      if ($callable = self::getCallable($class.':'.$method))
177
      {
178
        return call_user_func_array($callable, $parameters);
179
      }
180
      else
181
      {
182
        throw new Exception(sprintf('Call to undefined method %s::%s.', $class, $method));
183
      }
184
    }
185
    else
186
    {
187
      $hookName = $hookName ? $hookName : $method;
188
      foreach (self::getCallables($class.':'.$method.':'.$hookName) as $callable)
189
      {
190
        call_user_func_array($callable, $parameters);
191
      }
192
    }
193
  }
194
}