public
Description: A lightweight MVC framework on top of Grok-PHP
Homepage: http://chippino.googlecode.com
Clone URL: git://github.com/Jakobo/chippino.git
commit  c9650b37ef9ba2d0a2bbb3c2b5cc3f5e4ee29724
tree    2e3e1e9a10d8f6a2fd4f5e35ddcbd474116871d4
parent  06763113b720075f892460c584a5a8255d3f2379
chippino / chippino_core.php
100755 207 lines (169 sloc) 5.733 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
<?php
/**
* Chippino :: lightweight app framework
* Based on GROK by John Loehrer
* @author Jakob Heuser <jakob@felocity.org>
*/
 
define('CHIPPINO_LOCATION', dirname(__FILE__) . DIRECTORY_SEPARATOR);
define('CHIPPINO_LIBRARY_LOCATION', CHIPPINO_LOCATION . 'library' . DIRECTORY_SEPARATOR . 'chippino' . DIRECTORY_SEPARATOR);
 
/**
* Chippino initiator. used to create the chain
* @return Chippino_Dispatcher
* @param $file a string representing the chippino/grok file to include
**/
function chip($file = NULL) {
    $chip = new Chippino_Dispatcher();
  $file = strtolower($file);
    $chip->setPath($file);
 
  $backtrace = debug_backtrace();
  
  // find a valid file
  foreach ($backtrace as $bk => $trace) {
    $origin = $trace['file'];
    if (strpos($origin, 'chippino.php') !== FALSE || strpos($origin, 'chippino_core.php') !== FALSE || strpos($origin, 'grok.php') !== FALSE) {
      continue;
    }
    $chip->setOrigin($origin);
    break;
  }
  
  // does file's last segment begin with _
  if (strpos(substr($file, strrpos($file, '/') + 1), '_') !== 0) {
    return $chip;
  }
  
  // check access, must be same dir. Start by removing all absolute path matches
  // that could happen when people symlink. This shouldn't cause problems for
  // anyone, but anything is possible.
  $normalize = array(
    CHIPPINO_LIBRARY_LOCATION,
    strtolower(CHIPPINO_LIBRARY_LOCATION),
    chippino_config()->base_path . 'chippino' . DIRECTORY_SEPARATOR,
    strtolower(chippino_config()->base_path . 'chippino' . DIRECTORY_SEPARATOR),
  );
  
  $caller = dirname(str_replace($normalize, '', $chip->getFilePath()));
  $callee = dirname(str_replace($normalize, '', $chip->getOrigin()));
 
  if ($caller != $callee) {
    throw new Chippino_Access_Exception($callee, $caller);
  }
  
  return $chip;
}
 
/**
* variant of chip() returns a singleton instance as a convience method
* @see chip()
**/
function chipi($file = NULL, $namespace = NULL) {
  $chip = chip($file);
  $chip->asSingleton($namespace);
  return $chip;
}
 
/**
* return a static grok object for the purposes of setting a config
* @return Chippino_Container
**/
function chippino_config() {
    static $chip;
    if (!isset($chip)) {
        $chip = new Grok_Container();
    }
    return $chip;
}
 
/**
* Here is the actual Grok Class. Enjoy!
**/
class Chippino_Dispatcher {
  
  private $as_singleton;
  private $file_path;
  private $origin_path;
  
  public function __construct() {
    $this->as_singleton = FALSE;
    $this->file_path = NULL;
    $this->origin_path = NULL;
  }
  
    /**
* says that the dispatch should behave as a singleton (use a single instance)
* @param String $namespace [optional] a unique namespace
* @return Chippino_Dispatcher
**/
    public function asSingleton($namespace = NULL) {
        $this->as_singleton = $namespace;
        return $this;
    }
 
  public function getSingleton() {
    return ($this->as_singleton) ? $this->as_singleton : FALSE;
  }
  
  public function setOrigin($path) {
    $this->origin_path = $path;
  }
  
  public function getOrigin() {
    return $this->origin_path;
  }
 
  public function setPath($file = NULL) {
    $this->file_path = $file;
    return $this;
  }
  
  public function getPath() {
    return ($this->file_path) ? $this->file_path : NULL;
  }
  
  public function getFilePath() {
    $file = $this->getPath();
    
   // make sure we are using the correct filepath delimiter here
   if ('/' != DIRECTORY_SEPARATOR) {
   $file = str_replace('/', DIRECTORY_SEPARATOR, $file);
   }
 
   // add php suffix
   $file = chippino_config()->base_path . $file . '.php';
  
    return $file;
  }
    
    /**
* Dispatches a Chippino_Dispatcher with the supplied input parameters
* @param mixed the input, either an array or Chippino_Container
* @return mixed whatever the included file decides to return
**/
    public function with($input = NULL) {
        $grok = call_user_func_array(array(chippino_config()->chippino_class, 'retrieve'), array(
      $this->getPath(),
      $input,
      $this->getSingleton()
    ));
    
        return $grok->dispatch($this->getFilePath());
    }
}
 
class Chippino_Factory {
    /**
* gets an occurrence of a Chippino object
* the file creates a unique key to ID the grok. If it doesn't exist,
* then it is created. If $as_singleton is provided, it will look for
* and existing grok object in its data store
* This is called statically
* @param $file the filename to get
* @param $input an array of input to load into the object
* @param $singleton [optional] if the class should be retrieved from storage
* @return Chippino_Dispatcher
**/
    public static function retrieve($file, $input, $singleton = FALSE) {
        static $chips;
        
        if (!$singleton) {
            return new Grok($input);
        }
        
        if (!isset($chips)) {
            $chips = array();
        }
        
        // unique namespace
        $key = $singleton."#".$file;
        
        if (!isset($chips[$key])) {
            $chips[$key] = grok($file);
        }
        
        $chips[$key]->__construct($input);
        
        return $chips[$key];
    }
}
 
class Chippino_Access_Exception extends Exception {
  public function __construct($caller, $callee) {
    // strip base path from both
    $caller = strtolower(str_replace(array(chippino_config()->base_path, '.php'), '', $caller));
    $callee = strtolower(str_replace(array(chippino_config()->base_path, '.php'), '', $callee));
    parent::__construct('Access error: Attempt to call '.$caller.' from '.$callee);
  }
}
 
 
// default Chippino Config Values
chippino_config()->base_path = dirname(__FILE__) . DIRECTORY_SEPARATOR;
chippino_config()->chippino_class = 'Chippino_Factory';
 
// EOF