public
Description: The ultra-lightweight ultra-flexible blogging engine with a fetish for birds and misspellings.
Homepage: http://chyrp.net/
Clone URL: git://github.com/vito/chyrp.git
Click here to lend your support to: chyrp and make a donation at www.pledgie.com !
* Extensible authentication system. [#135 state:resolved]
  * Added a "visitor" filter that modifies the Visitor.
  * If an "authenticate" trigger exists...
    * Its functionality will be used instead of the standard log-in 
    functionality.
    * The Visitor::__construct() will not load a User object.
* Cleaned up the sequence of execution in common.php.
  * Visitor, Theme, and Route-parsed URL values are no longer available to 
  __init functions.
    Use the more appropriate "runtime" trigger instead.
  * Merged those two feather/module preparing loops into one.
* Documentation cleanups.
vito (author)
Sat Sep 06 12:28:46 -0700 2008
commit  a3d1c5c28f03588ac451190abd4957e766f56a19
tree    74490c7f50ceb1fec22f2c327e34497a25995abd
parent  7b38ea6d900434a89a0511e2c660bd2d893ab5c8
...
148
149
150
151
152
153
154
155
156
...
205
206
207
 
208
 
209
210
211
212
213
214
 
 
 
 
 
215
216
217
...
222
223
224
 
 
 
 
 
 
 
 
 
 
 
 
 
225
226
 
 
 
 
 
227
228
229
...
234
235
236
 
 
 
 
 
 
 
 
 
 
 
 
 
237
238
239
240
241
 
 
 
 
 
 
 
 
 
 
242
243
244
...
251
252
253
254
 
255
256
257
258
 
259
260
261
...
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
 
316
317
318
...
322
323
324
325
326
 
327
328
329
330
 
 
331
332
333
...
335
336
337
 
338
339
340
...
148
149
150
 
 
 
151
152
153
...
202
203
204
205
206
207
208
209
210
 
 
 
211
212
213
214
215
216
217
218
...
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
...
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
 
 
 
271
272
273
274
275
276
277
278
279
280
281
282
283
...
290
291
292
 
293
294
295
296
 
297
298
299
300
...
302
303
304
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
305
306
307
308
...
312
313
314
 
315
316
317
 
318
 
319
320
321
322
323
...
325
326
327
328
329
330
331
0
@@ -148,9 +148,6 @@
0
   #     <Session>
0
   require_once INCLUDES_DIR."/class/Session.php";
0
 
0
-  if (!JAVASCRIPT)
0
-    session();
0
-
0
   # File: Flash
0
   # See Also:
0
   #     <Flash>
0
@@ -205,13 +202,17 @@
0
   #     <Feather>
0
   require_once INCLUDES_DIR."/interface/Feather.php";
0
 
0
+  session();
0
   timer_start();
0
+  set_locale($config->locale);
0
 
0
   $flash = Flash::current();
0
 
0
-  set_locale($config->locale);
0
-
0
-  # Require feathers/modules and load their translations.
0
+  /**
0
+   * Array: $feathers
0
+   * Contains all of the enabled Feather's Classes.
0
+   */
0
+  $feathers = array();
0
   foreach ($config->enabled_feathers as $index => $feather) {
0
     if (!file_exists(FEATHERS_DIR."/".$feather."/".$feather.".php")) {
0
       unset($config->enabled_feathers[$index]);
0
@@ -222,8 +223,26 @@
0
       load_translator($feather, FEATHERS_DIR."/".$feather."/locale/".$config->locale.".mo");
0
 
0
     require FEATHERS_DIR."/".$feather."/".$feather.".php";
0
+
0
+    $camelized = camelize($feather);
0
+    if (!class_exists($camelized))
0
+      continue;
0
+
0
+    $feathers[$feather] = new $camelized;
0
+    $feathers[$feather]->safename = $feather;
0
+
0
+    if (!ADMIN and $route->action != "feed")
0
+      continue;
0
+
0
+    foreach (YAML::load(FEATHERS_DIR."/".$feather."/info.yaml") as $key => $val)
0
+      $feathers[$feather]->$key = (is_string($val)) ? __($val, $feather) : $val ;
0
   }
0
 
0
+  /**
0
+   * Array: $modules
0
+   * Contains all of the enabled Module's Classes.
0
+   */
0
+  $modules = array();
0
   foreach ($config->enabled_modules as $index => $module) {
0
     if (!file_exists(MODULES_DIR."/".$module."/".$module.".php")) {
0
       unset($config->enabled_modules[$index]);
0
@@ -234,11 +253,31 @@
0
       load_translator($module, MODULES_DIR."/".$module."/locale/".$config->locale.".mo");
0
 
0
     require MODULES_DIR."/".$module."/".$module.".php";
0
+
0
+    $camelized = camelize($module);
0
+    if (!class_exists($camelized))
0
+      continue;
0
+
0
+    $modules[$module] = new $camelized;
0
+    $modules[$module]->safename = $module;
0
+
0
+    if (!ADMIN)
0
+      continue;
0
+
0
+    foreach (YAML::load(MODULES_DIR."/".$module."/info.yaml") as $key => $val)
0
+      $modules[$module]->$key = (is_string($val)) ? __($val, $module) : $val ;
0
   }
0
 
0
-  # Load the /clean/urls into their correct $_GET values.
0
-  if (INDEX or ADMIN)
0
-    $route->determine_action();
0
+  # Now that they're all instantiated, call __init().
0
+  foreach ($feathers as $feather)
0
+    if (method_exists($feather, "__init"))
0
+      $feather->__init();
0
+
0
+  foreach ($modules as $module)
0
+    if (method_exists($module, "__init"))
0
+      $module->__init();
0
+
0
+  $route->determine_action();
0
 
0
   # Variable: $visitor
0
   # Holds the current user and their group.
0
@@ -251,11 +290,11 @@
0
   $theme = PREVIEWING ? $_GET['theme'] : $config->theme;
0
 
0
   # Constant: THEME_DIR
0
-  # Absolute path to /themes/(current theme)
0
+  # Absolute path to /themes/(current/previewed theme)
0
   define('THEME_DIR', MAIN_DIR."/themes/".$theme);
0
 
0
   # Constant: THEME_URL
0
-  # URL to /themes/(current theme)
0
+  # URL to /themes/(current/previewed theme)
0
   define('THEME_URL', $config->chyrp_url."/themes/".$theme);
0
 
0
   $theme = Theme::current();
0
@@ -263,56 +302,7 @@
0
   foreach (YAML::load(THEME_DIR."/info.yaml") as $key => $val)
0
     $theme->$key = $val;
0
 
0
-  if (INDEX)
0
-    header("Content-type: ".fallback($theme->type, "text/html")."; charset=UTF-8");
0
-  elseif (AJAX)
0
-    header("Content-type: text/html; charset=UTF-8");
0
-
0
-  # These are down here so that the modules are
0
-  # initialized after the $_GET values are filled.
0
-  /**
0
-   * Array: $feathers
0
-   * Contains all of the enabled Feather's Classes.
0
-   */
0
-  $feathers = array();
0
-  foreach ($config->enabled_feathers as $feather) {
0
-    $camelized = camelize($feather);
0
-    if (!class_exists($camelized)) continue;
0
-
0
-    $feathers[$feather] = new $camelized;
0
-    $feathers[$feather]->safename = $feather;
0
-
0
-    if (!ADMIN and $route->action != "feed") continue;
0
-
0
-    foreach (YAML::load(FEATHERS_DIR."/".$feather."/info.yaml") as $key => $val)
0
-      $feathers[$feather]->$key = (is_string($val)) ? __($val, $feather) : $val ;
0
-  }
0
-
0
-  /**
0
-   * Array: $modules
0
-   * Contains all of the enabled Module's Classes.
0
-   */
0
-  $modules = array();
0
-  foreach ($config->enabled_modules as $module) {
0
-    $camelized = camelize($module);
0
-    if (!class_exists($camelized)) continue;
0
-
0
-    $modules[$module] = new $camelized;
0
-    $modules[$module]->safename = $module;
0
-
0
-    if (!ADMIN) continue;
0
-
0
-    foreach (YAML::load(MODULES_DIR."/".$module."/info.yaml") as $key => $val)
0
-      $modules[$module]->$key = (is_string($val)) ? __($val, $module) : $val ;
0
-  }
0
-
0
-  # Now that they're all instantiated, call __init().
0
-  foreach ($feathers as $feather)
0
-    if (method_exists($feather, "__init"))
0
-      $feather->__init();
0
-  foreach ($modules as $module)
0
-    if (method_exists($module, "__init"))
0
-      $module->__init();
0
+  header("Content-type: ".(INDEX ? fallback($theme->type, "text/html") : "text/html")."; charset=UTF-8");
0
 
0
   if (INDEX) {
0
     $route->check_custom_routes();
0
@@ -322,12 +312,12 @@
0
       $route->check_viewing_page();
0
       $route->check_viewing_post(true);
0
     } else {
0
-      $route->check_viewing_post();
0
       $route->check_viewing_page(true);
0
+      $route->check_viewing_post();
0
     }
0
-  }
0
 
0
-  if (INDEX or ADMIN)
0
+    $trigger->call("runtime");
0
+  } elseif (ADMIN)
0
     $trigger->call("runtime");
0
 
0
   # Array: $statuses
0
@@ -335,6 +325,7 @@
0
   $statuses = array("public");
0
   if (logged_in())
0
     $statuses[] = "registered_only";
0
+
0
   if ($visitor->group()->can("view_private"))
0
     $statuses[] = "private";
0
 
...
223
224
225
 
 
 
 
 
226
227
228
...
223
224
225
226
227
228
229
230
231
232
233
0
@@ -223,6 +223,11 @@
0
       fallback($_POST['login']);
0
       fallback($_POST['password']);
0
 
0
+      $trigger = Trigger::current();
0
+
0
+      if ($trigger->exists("authenticate"))
0
+        return $trigger->call("authenticate");
0
+
0
       if (!User::authenticate($_POST['login'], md5($_POST['password'])))
0
         if (!count(User::find(array("where" => array("login" => $_POST['login'])))))
0
           Flash::warning(__("There is no user with that login name."));
...
602
603
604
 
 
 
605
606
607
...
626
627
628
629
 
630
631
632
...
1032
1033
1034
 
 
 
 
 
1035
1036
1037
...
602
603
604
605
606
607
608
609
610
...
629
630
631
 
632
633
634
635
...
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
0
@@ -602,6 +602,9 @@
0
    *
0
    * Returns:
0
    *     A CamelCased string.
0
+   *
0
+   * See Also:
0
+   *     <decamelize>
0
    */
0
   function camelize($string, $keep_spaces = false) {
0
     $lower = strtolower($string);
0
@@ -626,7 +629,7 @@
0
    *     A de_camel_cased string.
0
    *
0
    * See Also:
0
-   * <camelize>
0
+   *     <camelize>
0
    */
0
   function decamelize($string) {
0
     return strtolower(preg_replace("/([a-z])([A-Z])/", "\\1_\\2", $string));
0
@@ -1032,6 +1035,11 @@
0
    function cancel_module($target) {
0
     $this_disabled = array();
0
 
0
+    global $modules;
0
+
0
+    if (isset($modules[$target]))
0
+      $modules[$target]->cancelled = true;
0
+
0
     $config = Config::current();
0
     foreach ($config->enabled_modules as $module)
0
       if ($module != $target)
...
219
220
221
222
 
223
224
225
...
219
220
221
 
222
223
224
225
0
@@ -219,7 +219,7 @@ $(this).parent().find("ul:first").append(ui.draggable);self.element.data("sortab
0
       var self = this;
0
       this.interval = window.setInterval(function() { self.checkExpand() }, 400);
0
       // this.textarea.keydown(function() {
0
-      //   self.checkExpand()
0
+      //     self.checkExpand()
0
       // })
0
     },
0
     stopExpand: function() {
...
4
5
6
 
7
8
9
...
4
5
6
7
8
9
10
0
@@ -4,6 +4,7 @@
0
   /**
0
    * Class: Group
0
    * The Group model.
0
+   *
0
    * See Also:
0
    *     <Model>
0
    */
...
2
3
4
 
5
6
7
...
2
3
4
5
6
7
8
0
@@ -2,6 +2,7 @@
0
   /**
0
    * Class: Page
0
    * The Page model.
0
+   *
0
    * See Also:
0
    *     <Model>
0
    */
...
2
3
4
 
5
6
7
...
2
3
4
5
6
7
8
0
@@ -2,6 +2,7 @@
0
   /**
0
    * Class: Post
0
    * The Post model.
0
+   *
0
    * See Also:
0
    *     <Model>
0
    */
...
2
3
4
 
5
6
7
...
2
3
4
5
6
7
8
0
@@ -2,6 +2,7 @@
0
   /**
0
    * Class: User
0
    * The User model.
0
+   *
0
    * See Also:
0
    *     <Model>
0
    */
...
2
3
4
 
5
6
7
...
15
16
17
18
19
20
 
 
 
 
 
 
 
21
22
23
...
2
3
4
5
6
7
8
...
16
17
18
 
 
 
19
20
21
22
23
24
25
26
27
28
0
@@ -2,6 +2,7 @@
0
   /**
0
    * Class: Visitor
0
    * The model for the currently browsing <User>. Group falls back to whatever group is set as the "Guest Group".
0
+   *
0
    * See Also:
0
    *     <User>
0
    */
0
@@ -15,9 +16,13 @@
0
      * Checks if a valid user is logged in.
0
      */
0
     public function __construct() {
0
-      if (isset($_SESSION['login']) and isset($_SESSION['password']))
0
-        parent::__construct(null, array("where"  => array("login"    => $_SESSION['login'],
0
-                                                          "password" => $_SESSION['password'])));
0
+      $trigger = Trigger::current();
0
+
0
+      if (!$trigger->exists("authenticate") and isset($_SESSION['login']) and isset($_SESSION['password']))
0
+        parent::__construct(null, array("where" => array("login"    => $_SESSION['login'],
0
+                                                         "password" => $_SESSION['password'])));
0
+
0
+      $trigger->filter($this, "visitor");
0
     }
0
 
0
     /**
...
1
2
3
 
 
 
 
 
 
 
 
 
 
 
4
5
6
...
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 
 
 
33
34
35
...
1
2
 
3
4
5
6
7
8
9
10
11
12
13
14
15
16
...
28
29
30
 
 
 
 
 
 
 
 
 
 
31
 
32
33
34
35
36
37
0
@@ -1,6 +1,16 @@
0
 <?php
0
   class Cacher extends Modules {
0
-    public function __init() {
0
+    static function __install() {
0
+      $config = Config::current();
0
+      $config->set("cache_expire", 1800);
0
+    }
0
+
0
+    static function __uninstall() {
0
+      $config = Config::current();
0
+      $config->remove("cache_expire");
0
+    }
0
+
0
+    public function prepare() {
0
       $this->user = (logged_in()) ? Visitor::current()->login : "guest" ;
0
       $this->caches = INCLUDES_DIR."/caches";
0
       $this->path = INCLUDES_DIR."/caches/".sanitize($this->user);
0
@@ -18,18 +28,10 @@
0
       $this->remove_expired();
0
     }
0
 
0
-    static function __install() {
0
-      $config = Config::current();
0
-      $config->set("cache_expire", 1800);
0
-    }
0
-
0
-    static function __uninstall() {
0
-      $config = Config::current();
0
-      $config->remove("cache_expire");
0
-    }
0
-
0
     public function runtime() {
0
-      if (!file_exists($this->file) or Flash::exists())
0
+      $this->prepare();
0
+
0
+      if ($this->cancelled or !file_exists($this->file) or Flash::exists())
0
         return;
0
 
0
       $action = Route::current()->action;
...
2
3
4
 
 
 
5
6
7
...
2
3
4
5
6
7
8
9
10
0
@@ -2,6 +2,9 @@
0
   /**
0
    * Class: Comment
0
    * The model for the Comments SQL table.
0
+   *
0
+   * See Also:
0
+   *     <Model>
0
    */
0
   class Comment extends Model {
0
     public $no_results = false;

Comments