1: <?php
2: /**
3: * This file contains the the backend and frontend session class.
4: *
5: * @package Core
6: * @subpackage Session
7: * @version SVN Revision $Rev:$
8: *
9: * @author Frederic Schneider
10: * @copyright four for business AG <www.4fb.de>
11: * @license http://www.contenido.org/license/LIZENZ.txt
12: * @link http://www.4fb.de
13: * @link http://www.contenido.org
14: */
15:
16: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
17:
18: /**
19: * Backend session class.
20: *
21: * @package Core
22: * @subpackage Session
23: */
24: class cSession {
25:
26: /**
27: * Saves the registered variables
28: *
29: * @var array
30: */
31: protected $_pt;
32:
33: /**
34: * The prefix for the session variables
35: *
36: * @var string
37: */
38: protected $_prefix;
39:
40: /**
41: * Placeholder.
42: * This variable isn't needed to make sessions work any longer
43: * but some CONTENIDO functions/classes rely on it
44: *
45: * @var string
46: */
47: public $id;
48:
49: /**
50: * Placeholder.
51: * This variable isn't needed to make sessions work any longer
52: * but some CONTENIDO functions/classes rely on it
53: *
54: * @var string
55: */
56: public $name;
57:
58: /**
59: * Starts the session
60: *
61: * @param string $prefix The prefix for the session variables
62: */
63: public function __construct($prefix = 'backend') {
64: $this->_pt = array();
65: $this->_prefix = $prefix;
66:
67: $this->name = 'contenido';
68:
69: if (!isset($_SESSION)) {
70: if ('backend' === $prefix) {
71: $url = cRegistry::getBackendUrl();
72: } else {
73: $url = cRegistry::getFrontendUrl();
74: }
75:
76: // remove protocol from contenido URL
77: $start = strpos($url, '://');
78: if (false === $start) {
79: $url = 'http://' . $url;
80: $start = strpos($url, '://');
81: }
82:
83: // url of contenido folder with hostname
84: $path = substr($url, $start + 3);
85:
86: $start = strpos($path, '/');
87: if (false !== $start) {
88: $path = substr($path, $start);
89: session_set_cookie_params(0, $path);
90: } else {
91: // fall back to entire domain if no path can be computed
92: session_set_cookie_params(0, '/');
93: }
94:
95: session_name($this->_prefix);
96: session_start();
97: $this->id = session_id();
98: }
99: }
100:
101: /**
102: * Registers a global variable which will become persistent
103: *
104: * @param string $things The name of the variable (e.g. "idclient")
105: */
106: public function register($things) {
107: $things = explode(',', $things);
108:
109: foreach ($things as $thing) {
110: $thing = trim($thing);
111: if ($thing) {
112: $this->_pt[$thing] = true;
113: }
114: }
115: }
116:
117: /**
118: * Unregisters a variable
119: *
120: * @param string $name The name of the variable (e.g. "idclient")
121: */
122: public function unregister($name) {
123: $this->_pt[$name] = false;
124: }
125:
126: /**
127: * Checks if a variable is registered
128: *
129: * @param string $name The name of the variable (e.g. "idclient")
130: * @return boolean
131: */
132: public function isRegistered($name) {
133: if (isset($this->_pt[$name]) && $this->_pt[$name] == true) {
134: return true;
135: }
136: return false;
137: }
138:
139: /**
140: * Attaches "&contenido=sessionid" at the end of the URL.
141: * This is no longer needed to make sessions work but some CONTENIDO
142: * functions/classes rely on it
143: *
144: * @param string $url A URL
145: * @return mixed
146: */
147: public function url($url) {
148:
149: // Remove existing session info from url
150: $url = preg_replace('/([&?])' . quotemeta(urlencode($this->name)) . '=1(&|$)/', "\\1", $url);
151:
152: // Remove trailing ?/& if needed
153: $url = preg_replace('/[&?]+$/', '', $url);
154:
155: if (!preg_match('~\b' . quotemeta(urlencode($this->name)) . '=[a-zA-Z0-9]*\b~', $url)) {
156: $url .= (strpos($url, '?') != false? '&' : '?') . urlencode($this->name) . '=' . $this->id;
157: }
158:
159: // Encode naughty characters in the URL
160: $url = str_replace(array(
161: '<',
162: '>',
163: ' ',
164: '"',
165: '\''
166: ), array(
167: '%3C',
168: '%3E',
169: '+',
170: '%22',
171: '%27'
172: ), $url);
173: return $url;
174: }
175:
176: /**
177: * Attaches "&contenido=1" at the end of the current URL.
178: * This is no longer needed to make sessions work but some CONTENIDO
179: * functions/classes rely on it
180: *
181: * @return mixed
182: */
183: public function selfURL() {
184: return $this->url($_SERVER['PHP_SELF'] . ((isset($_SERVER['QUERY_STRING']) && ('' != $_SERVER['QUERY_STRING'])) ? '?' . $_SERVER['QUERY_STRING'] : ''));
185: }
186:
187: /**
188: * Returns PHP code which can be used to rebuild the variable by evaluating
189: * it.
190: * This will work recursevly on arrays
191: *
192: * @param mixed $var A variable which should get serialized.
193: * @return string the PHP code which can be evaluated.
194: */
195: public function serialize($var) {
196: $str = "";
197: $this->_rSerialize($var, $str);
198: return $str;
199: }
200:
201: /**
202: * This function will go recursevly through arrays and objects to serialize
203: * them.
204: *
205: * @param mixed $var The variable
206: * @param string $str The PHP code will be attached to this string
207: */
208: protected function _rSerialize($var, &$str) {
209: static $t, $l, $k;
210:
211: // Determine the type of $$var
212: eval("\$t = gettype(\$$var);");
213: switch ($t) {
214: case 'array':
215: // $$var is an array. Enumerate the elements and serialize them.
216: eval("reset(\$$var); \$l = gettype(list(\$k)=each(\$$var));");
217: $str .= "\$$var = array(); ";
218: while ('array' == $l) {
219: // Structural recursion
220: $this->_rSerialize($var . "['" . preg_replace("/([\\'])/", "\\\\1", $k) . "']", $str);
221: eval("\$l = gettype(list(\$k)=each(\$$var));");
222: }
223: break;
224: case 'object':
225: // $$var is an object. Enumerate the slots and serialize them.
226: eval("\$k = \$${var}->classname; \$l = reset(\$${var}->persistent_slots);");
227: $str .= "\$$var = new $k; ";
228: while ($l) {
229: // Structural recursion.
230: $this->_rSerialize($var . "->" . $l, $str);
231: eval("\$l = next(\$${var}->persistent_slots);");
232: }
233: break;
234: default:
235: // $$var is an atom. Extract it to $l, then generate code.
236: eval("\$l = \$$var;");
237: $str .= "\$$var = '" . preg_replace("/([\\'])/", "\\\\1", $l) . "'; ";
238: break;
239: }
240: }
241:
242: /**
243: * Stores the session using PHP's own session implementation
244: */
245: public function freeze() {
246: $str = $this->serialize("this->_pt");
247:
248: foreach ($this->_pt as $thing => $value) {
249: $thing = trim($thing);
250: if ($value) {
251: $str .= $this->serialize("GLOBALS['" . $thing . "']");
252: }
253: }
254:
255: $_SESSION[$this->_prefix . 'csession'] = $str;
256: }
257:
258: /**
259: * Rebuilds every registered variable from the session.
260: */
261: public function thaw() {
262: if (isset($_SESSION[$this->_prefix . 'csession']) && $_SESSION[$this->_prefix . 'csession'] != '') {
263: eval(sprintf(';%s', $_SESSION[$this->_prefix . 'csession']));
264: }
265: }
266:
267: /**
268: * Deletes the session by calling session_destroy()
269: */
270: public function delete() {
271: $params = session_get_cookie_params();
272: setcookie(session_name(), '', time() - 600, $params['path'], $params['domain'], $params['secure'], $params['httponly']);
273:
274: session_destroy();
275: }
276:
277: /**
278: * Starts the session and rebuilds the variables
279: */
280: public function start() {
281: $this->thaw();
282: }
283: }
284:
285: /**
286: * Session class for the frontend.
287: * It uses a different prefix. The rest is the
288: * same
289: *
290: * @package Core
291: * @subpackage Session
292: */
293: class cFrontendSession extends cSession {
294:
295: /**
296: * Starts the session and initilializes the class
297: */
298: public function __construct() {
299: $client = cRegistry::getClientId();
300:
301: parent::__construct($client . "frontend");
302: }
303:
304: /**
305: * This function overrides cSession::url() so that the contenido=1 isn't
306: * attached to the URL for the frontend
307: *
308: * @see cSession::url()
309: * @param string $url A URL
310: * @return mixed
311: */
312: public function url($url) {
313: $url = preg_replace('/([&?])' . quotemeta(urlencode($this->name)) . '=' . $this->id . '(&|$)/', "\\1", $url);
314:
315: $url = preg_replace('/[&?]+$/', '', $url);
316:
317: $url = str_replace(array(
318: '<',
319: '>',
320: ' ',
321: '"',
322: '\''
323: ), array(
324: '%3C',
325: '%3E',
326: '+',
327: '%22',
328: '%27'
329: ), $url);
330:
331: return $url;
332: }
333: }
334:
335: ?>