Subversion Repositories PHPX

Rev

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

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