Subversion Repositories PHPX

Rev

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