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: */
115: public function isRegistered($name) {
116: if (isset($this->_pt[$name]) && $this->_pt[$name] == true) {
117: return true;
118: }
119: return false;
120: }
121:
122: /**
123: * Attaches "&contenido=sessionid" at the end of the URL.
124: * This is no longer needed
125: * to make sessions work but some CONTENIDO functions/classes rely on it
126: *
127: * @param string $url A URL
128: */
129: public function url($url) {
130:
131: // Remove existing session info from url
132: $url = preg_replace('/([&?])' . quotemeta(urlencode($this->name)) . '=1(&|$)/', "\\1", $url);
133:
134: // Remove trailing ?/& if needed
135: $url = preg_replace('/[&?]+$/', '', $url);
136:
137: if (!preg_match('~\b' . quotemeta(urlencode($this->name)) . '=[a-zA-Z0-9]*\b~', $url)) {
138: $url .= (strpos($url, '?') != false? '&' : '?') . urlencode($this->name) . '=' . $this->id;
139: }
140:
141: // Encode naughty characters in the URL
142: $url = str_replace(array(
143: '<',
144: '>',
145: ' ',
146: '"',
147: '\''
148: ), array(
149: '%3C',
150: '%3E',
151: '+',
152: '%22',
153: '%27'
154: ), $url);
155: return $url;
156: }
157:
158: /**
159: * Attaches "&contenido=1" at the end of the current URL.
160: * This is no longer
161: * needed to make sessions work but some CONTENIDO functions/classes rely on
162: * it
163: *
164: * @param string $url A URL
165: */
166: public function selfURL() {
167: return $this->url($_SERVER['PHP_SELF'] . ((isset($_SERVER['QUERY_STRING']) && ('' != $_SERVER['QUERY_STRING']))? '?' . $_SERVER['QUERY_STRING'] : ''));
168: }
169:
170: /**
171: * Returns PHP code which can be used to rebuild the variable by evaluating
172: * it.
173: * This will work recursevly on arrays
174: *
175: * @param mixed $var A variable which should get serialized.
176: * @return string the PHP code which can be evaluated.
177: */
178: public function serialize($var) {
179: $str = "";
180: $this->_rSerialize($var, $str);
181: return $str;
182: }
183:
184: /**
185: * This function will go recursevly through arrays and objects to serialize
186: * them.
187: *
188: * @param mixed $var The variable
189: * @param string $str The PHP code will be attached to this string
190: */
191: protected function _rSerialize($var, &$str) {
192: static $t, $l, $k;
193:
194: // Determine the type of $$var
195: eval("\$t = gettype(\$$var);");
196: switch ($t) {
197: case 'array':
198: // $$var is an array. Enumerate the elements and serialize them.
199: eval("reset(\$$var); \$l = gettype(list(\$k)=each(\$$var));");
200: $str .= "\$$var = array(); ";
201: while ('array' == $l) {
202: // Structural recursion
203: $this->_rSerialize($var . "['" . preg_replace("/([\\'])/", "\\\\1", $k) . "']", $str);
204: eval("\$l = gettype(list(\$k)=each(\$$var));");
205: }
206: break;
207: case 'object':
208: // $$var is an object. Enumerate the slots and serialize them.
209: eval("\$k = \$${var}->classname; \$l = reset(\$${var}->persistent_slots);");
210: $str .= "\$$var = new $k; ";
211: while ($l) {
212: // Structural recursion.
213: $this->_rSerialize($var . "->" . $l, $str);
214: eval("\$l = next(\$${var}->persistent_slots);");
215: }
216: break;
217: default:
218: // $$var is an atom. Extract it to $l, then generate code.
219: eval("\$l = \$$var;");
220: $str .= "\$$var = '" . preg_replace("/([\\'])/", "\\\\1", $l) . "'; ";
221: break;
222: }
223: }
224:
225: /**
226: * Stores the session using PHP's own session implementation
227: */
228: public function freeze() {
229: $str = $this->serialize("this->_pt");
230:
231: foreach ($this->_pt as $thing => $value) {
232: $thing = trim($thing);
233: if ($value) {
234: $str .= $this->serialize("GLOBALS['" . $thing . "']");
235: }
236: }
237:
238: $_SESSION[$this->_prefix . 'csession'] = $str;
239: }
240:
241: /**
242: * Rebuilds every registered variable from the session.
243: */
244: public function thaw() {
245: if (isset($_SESSION[$this->_prefix . 'csession']) && $_SESSION[$this->_prefix . 'csession'] != '') {
246: eval(sprintf(';%s', $_SESSION[$this->_prefix . 'csession']));
247: }
248: }
249:
250: /**
251: * Deletes the session by calling session_destroy()
252: */
253: public function delete() {
254: $params = session_get_cookie_params();
255: setcookie(session_name(), '', time() - 600, $params['path'], $params['domain'], $params['secure'], $params['httponly']);
256:
257: session_destroy();
258: }
259:
260: /**
261: * Starts the session and rebuilds the variables
262: */
263: public function start() {
264: $this->thaw();
265: }
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: */
294: public function url($url) {
295: $url = preg_replace('/([&?])' . quotemeta(urlencode($this->name)) . '=' . $this->id . '(&|$)/', "\\1", $url);
296:
297: $url = preg_replace('/[&?]+$/', '', $url);
298:
299: $url = str_replace(array(
300: '<',
301: '>',
302: ' ',
303: '"',
304: '\''
305: ), array(
306: '%3C',
307: '%3E',
308: '+',
309: '%22',
310: '%27'
311: ), $url);
312:
313: return $url;
314: }
315:
316: }
317:
318: ?>