Subversion Repositories PHPX

Rev

Rev 51 | Rev 57 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
27 PointedEar 1
<?php
2
 
51 PointedEar 3
namespace PointedEars\PHPX;
4
 
52 PointedEar 5
function autoload ($class)
6
{
7
        if (\strpos($class, '..'))
8
        {
9
                throw new \InvalidArgumentException(
10
                        'Refusing to load unsafe class ' . $class);
11
        }
27 PointedEar 12
 
52 PointedEar 13
        require_once \preg_replace('#\\\#', '/',
14
                \preg_replace('#^' . \preg_quote(__NAMESPACE__) .'#', __DIR__, $class)
15
        ) . '.php';
16
}
17
 
18
\spl_autoload_register(__NAMESPACE__ . '\\autoload');
19
 
27 PointedEar 20
/**
21
 * Basic application class
22
 *
23
 * @author Thomas Lahn
24
 */
25
class Application
26
{
27
  /**
28
   * Relative path to the controllers directory
29
   * @var string
30
   */
31
  protected $_controllerPath = 'application/controllers';
45 PointedEar 32
 
27 PointedEar 33
  /**
34
   * Default controller of the application
35
   * @var string
36
   */
37
  protected $_defaultController = 'Index';
45 PointedEar 38
 
27 PointedEar 39
  /**
40
   * Registry key for the default database of the application
41
   * @var string
42
   */
43
  protected $_defaultDatabase;
45 PointedEar 44
 
27 PointedEar 45
  /**
46
   * Currently active controller of this application
47
   * @var Controller
48
   */
49
  protected $_currentController;
45 PointedEar 50
 
27 PointedEar 51
  /**
52
   * Singleton
53
   *
54
   * @var Application
55
   */
56
  private static $_instance;
45 PointedEar 57
 
52 PointedEar 58
  protected function __construct ()
27 PointedEar 59
  {
60
    /* Singleton pattern */
61
  }
45 PointedEar 62
 
27 PointedEar 63
  /**
64
   * Gets a reference to the <code>Application</code> instance
65
   *
66
   * @param Application $instance
67
   *   The instance to be used as application.  The default is a new
68
   *   application.  This parameter is ignored if the application was
69
   *   already initialized.
70
   * @return Application
71
   */
52 PointedEar 72
  public static function getInstance (Application $instance = null)
27 PointedEar 73
  {
31 PointedEar 74
    if (self::$_instance === null)
27 PointedEar 75
    {
76
      self::$_instance = ($instance === null) ? new self() : $instance;
77
    }
45 PointedEar 78
 
27 PointedEar 79
    return self::$_instance;
80
  }
45 PointedEar 81
 
31 PointedEar 82
  /**
83
   * Getter for properties
84
   *
85
   * @param string $name
86
   * @throws ModelPropertyException
87
   * @return mixed
88
   */
52 PointedEar 89
  public function __get ($name)
31 PointedEar 90
  {
91
    /* Support for Object-Relational Mappers */
52 PointedEar 92
    if (\strpos($name, 'persistent') === 0)
31 PointedEar 93
    {
52 PointedEar 94
      $class = \get_class($this);
34 PointedEar 95
      return $class::${$name};
31 PointedEar 96
    }
45 PointedEar 97
 
52 PointedEar 98
    $method = 'get' . \ucfirst($name);
45 PointedEar 99
 
52 PointedEar 100
    if (\method_exists($this, $method))
31 PointedEar 101
    {
102
      return $this->$method();
103
    }
45 PointedEar 104
 
52 PointedEar 105
    if (\property_exists($this, "_$name"))
31 PointedEar 106
    {
107
      return $this->{"_$name"};
108
    }
45 PointedEar 109
 
31 PointedEar 110
    return $this->$name;
111
  }
45 PointedEar 112
 
27 PointedEar 113
  /**
31 PointedEar 114
   * Setter for properties
115
   *
116
   * @param string $name
117
   * @param mixed $value  The new property value before assignment
118
   * @throws ModelPropertyException
119
   */
52 PointedEar 120
  public function __set ($name, $value)
31 PointedEar 121
  {
52 PointedEar 122
    $method = 'set' . \ucfirst($name);
45 PointedEar 123
 
52 PointedEar 124
    if (\method_exists($this, $method))
31 PointedEar 125
    {
126
      return $this->$method($value);
127
    }
45 PointedEar 128
 
52 PointedEar 129
    if (\property_exists($this, "_$name"))
31 PointedEar 130
    {
131
      $this->{"_$name"} = $value;
132
      return $this->{"_$name"};
133
    }
45 PointedEar 134
 
31 PointedEar 135
    /* NOTE: Attempts to set other properties are _silently_ _ignored_ */
136
  }
45 PointedEar 137
 
31 PointedEar 138
  /**
27 PointedEar 139
   * Runs the application, setting up session management and
140
   * constructing the controller indicated by the URI
141
   */
52 PointedEar 142
  public function run ()
27 PointedEar 143
  {
144
    $this->startSession();
45 PointedEar 145
 
27 PointedEar 146
    $controller = self::getParam('controller', $_REQUEST);
147
    if (!$controller)
148
    {
149
      $controller = $this->_defaultController;
150
    }
151
 
52 PointedEar 152
    $controller = \ucfirst($controller);
45 PointedEar 153
 
27 PointedEar 154
    $controller = $controller . 'Controller';
155
    require_once "{$this->_controllerPath}/{$controller}.php";
156
    $this->_currentController = new $controller();
45 PointedEar 157
 
27 PointedEar 158
    return $this;
159
  }
160
 
52 PointedEar 161
  protected function startSession ()
27 PointedEar 162
  {
52 PointedEar 163
    \session_start();
27 PointedEar 164
  }
45 PointedEar 165
 
27 PointedEar 166
  /**
167
   * Gets a request parameter
168
   *
169
   * @param string $key
170
   *   Key to look up in the array
171
   * @param array $array
172
   *   Array where to look up <var>$key</var>.
173
   *   The default is <code>$_GET</code>.
174
   * @return mixed
175
   *   <code>null</code> if there is no such <var>$key</var>
176
   *   in <var>$array</var>
177
   */
52 PointedEar 178
  public static function getParam ($key, array $array = null)
27 PointedEar 179
  {
31 PointedEar 180
    if ($array === null)
27 PointedEar 181
    {
182
      $array = $_GET;
183
    }
45 PointedEar 184
 
27 PointedEar 185
    return isset($array[$key]) ? $array[$key] : null;
186
  }
45 PointedEar 187
 
27 PointedEar 188
  /**
189
   * Registers a database
190
   *
191
   * @param string $key
192
   * @param Database $database
45 PointedEar 193
   * @return string Registry key
194
   * @see Application::setDefaultDatabase()
27 PointedEar 195
   */
51 PointedEar 196
  public function registerDatabase ($key, Db\Database $database)
27 PointedEar 197
  {
198
    Registry::set($key, $database);
45 PointedEar 199
    return $key;
27 PointedEar 200
  }
201
 
202
  /**
203
   * Sets the default database
45 PointedEar 204
   * @param string Registry key to refer to the {@link Database}
27 PointedEar 205
   */
45 PointedEar 206
  public function setDefaultDatabase ($key)
27 PointedEar 207
  {
208
    $this->_defaultDatabase = $key;
209
  }
210
 
211
  /**
212
  * Sets the current controller for this application
213
  *
214
  * @param Controller $controller
215
  * @return Application
216
  */
52 PointedEar 217
  public function setCurrentController (Controller $controller)
27 PointedEar 218
  {
219
    $this->_currentController = $controller;
220
    return $this;
221
  }
45 PointedEar 222
 
27 PointedEar 223
  /**
224
   * Returns the current controller for this application
225
   *
226
   * @return Controller
227
   */
52 PointedEar 228
  public function getCurrentController ()
27 PointedEar 229
  {
230
    return $this->_currentController;
231
  }
232
 
233
  /**
234
   * Returns the default database for this application
235
   *
236
   * @return Database
237
   */
52 PointedEar 238
  public function getDefaultDatabase ()
27 PointedEar 239
  {
240
    return Registry::get($this->_defaultDatabase);
241
  }
242
 
243
  /**
35 PointedEar 244
   * Returns a relative URI-reference for an action of the
27 PointedEar 245
   * application
246
   *
247
   * @param string[optional] $controller
248
   * @param string[optional] $action
249
   * @param int[optional] $id
250
   */
52 PointedEar 251
  public function getURL ($controller = null, $action = null, $id = null)
27 PointedEar 252
  {
253
    /* Apache module */
254
    $url = self::getParam('SCRIPT_URL', $_SERVER);
255
    if ($url === null)
256
    {
257
      /* FastCGI */
258
      $url = self::getParam('URL', $_SERVER);
259
      if ($url === null)
260
      {
31 PointedEar 261
        /* Server/PHP too old, compute URI */
262
        $url = self::getParam('REQUEST_URI', $_SERVER);
52 PointedEar 263
        if (\preg_match('/^[^?]+/', $url, $matches) > 0)
31 PointedEar 264
        {
265
          $url = $matches[0];
266
        }
267
        else
268
        {
269
          /* Has .php in it, but at least it works */
270
          $url = self::getParam('SCRIPT_NAME', $_SERVER);
271
          if ($url === null)
272
          {
52 PointedEar 273
            throw new \Exception(
31 PointedEar 274
              'None of $_SERVER["SCRIPT_URL"], $_SERVER["URL"],'
275
              . ' $_SERVER["REQUEST_URI"], or $_SERVER["SCRIPT_NAME"]'
276
              . ' is available, cannot continue.');
277
          }
278
        }
27 PointedEar 279
      }
280
    }
45 PointedEar 281
 
31 PointedEar 282
    $query = (($controller !== null) ? 'controller=' . $controller : '')
283
           . (($action !== null) ? '&action=' . $action : '')
284
           . (($id !== null) ? '&id=' . $id : '');
45 PointedEar 285
 
27 PointedEar 286
    return $url . ($query ? '?' . $query : '');
287
  }
45 PointedEar 288
 
27 PointedEar 289
  /**
290
   * Performs a server-side redirect within the application
291
   */
52 PointedEar 292
  public static function redirect ($query = '')
27 PointedEar 293
  {
294
    $script_uri = self::getParam('SCRIPT_URI', $_SERVER);
31 PointedEar 295
    if ($script_uri === null)
27 PointedEar 296
    {
297
      /* Server/PHP too old, compute URI */
52 PointedEar 298
      if (\preg_match('/^[^?]+/',
27 PointedEar 299
          self::getParam('REQUEST_URI', $_SERVER), $matches) > 0)
300
      {
301
        $query_prefix = $matches[0];
302
      }
303
      else
304
      {
305
        /* Has .php in it, but at least it works */
306
        $query_prefix = self::getParam('SCRIPT_NAME', $_SERVER);
307
      }
308
 
309
      /* TODO: Let user decide which ports map to which URI scheme */
310
      $script_uri = (self::getParam('SERVER_PORT', $_SERVER) == 443
311
                      ? 'https://'
312
                      : 'http://')
313
                  . self::getParam('HTTP_HOST', $_SERVER)
314
                  . $query_prefix;
315
    }
316
 
52 PointedEar 317
    \header('Location: ' . $script_uri
27 PointedEar 318
      . ($query ? (substr($query, 0, 1) === '?' ? '' : '?') . $query : ''));
319
  }
52 PointedEar 320
}