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