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