Subversion Repositories PHPX

Rev

Rev 45 | Rev 52 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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