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