Statistics
| Revision:

root / tags / typolight-2.7.5 / system / modules / backend / Backend.php

History | View | Annotate | Download (12.7 KB)

1
<?php if (!defined('TL_ROOT')) die('You can not access this file directly!');
2
3
/**
4
 * TYPOlight webCMS
5
 * Copyright (C) 2005-2009 Leo Feyer
6
 *
7
 * This program is free software: you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation, either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 * 
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
 * Lesser General Public License for more details.
16
 * 
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this program. If not, please visit the Free
19
 * Software Foundation website at http://www.gnu.org/licenses/.
20
 *
21
 * PHP version 5
22
 * @copyright  Leo Feyer 2005-2009
23
 * @author     Leo Feyer <leo@typolight.org>
24
 * @package    Backend
25
 * @license    LGPL
26
 * @filesource
27
 */
28
29
30
/**
31
 * Class Backend
32
 *
33
 * Provide methods to manage back end controllers.
34
 * @copyright  Leo Feyer 2005-2009
35
 * @author     Leo Feyer <leo@typolight.org>
36
 * @package    Controller
37
 */
38
abstract class Backend extends Controller
39
{
40
41
        /**
42
         * Load database object
43
         */
44
        protected function __construct()
45
        {
46
                parent::__construct();
47
                $this->import('Database');
48
        }
49
50
51
        /**
52
         * Open a back end module and return it as HTML
53
         * @param string
54
         * @return string
55
         */
56
        protected function getBackendModule($module)
57
        {
58
                $arrModule = array();
59
60
                foreach ($GLOBALS['BE_MOD'] as $arrGroup)
61
                {
62
                        if (count($arrGroup) && in_array($module, array_keys($arrGroup)))
63
                        {
64
                                $arrModule =& $arrGroup[$module];
65
                        }
66
                }
67
68
                $arrInactiveModules = deserialize($GLOBALS['TL_CONFIG']['inactiveModules']);
69
70
                // Check whether the module is active
71
                if (is_array($arrInactiveModules) && in_array($module, $arrInactiveModules))
72
                {
73
                        $this->log('Attempt to access inactive back end module "' . $module . '"', 'Backend getBackendModule()', TL_ACCESS);
74
                        $this->redirect('typolight/main.php?act=error');
75
                }
76
77
                $this->import('BackendUser', 'User');
78
79
                // Check whether the current user has access to the current module
80
                if (!in_array($module, array_keys($GLOBALS['BE_MOD']['profile'])) && !$this->User->isAdmin && !$this->User->hasAccess($module, 'modules'))
81
                {
82
                        $this->log('Back end module "' . $module . '" was not allowed for user "' . $this->User->username . '"', 'Backend getBackendModule()', TL_ERROR);
83
                        $this->redirect('typolight/main.php?act=error');
84
                }
85
86
                $strTable = $this->Input->get('table') ? $this->Input->get('table') : $arrModule['tables'][0];
87
                $id = (!$this->Input->get('act') && $this->Input->get('id')) ? $this->Input->get('id') : $this->Session->get('CURRENT_ID');
88
89
                // Store the current ID in the current session
90
                if ($id != $this->Session->get('CURRENT_ID'))
91
                {
92
                        $this->Session->set('CURRENT_ID', $id);
93
                        $this->reload();
94
                }
95
96
                define('CURRENT_ID', ($this->Input->get('table') ? $id : $this->Input->get('id')));
97
                $this->Template->headline = $GLOBALS['TL_LANG']['MOD'][$module][0];
98
99
                // Add module style sheet
100
                if (isset($arrModule['stylesheet']))
101
                {
102
                        $GLOBALS['TL_CSS'][] = $arrModule['stylesheet'];
103
                }
104
105
                // Add module javascript
106
                if (isset($arrModule['javascript']))
107
                {
108
                        $GLOBALS['TL_JAVASCRIPT'][] = $arrModule['javascript'];
109
                }
110
111
                // Redirect if the current table does not belong to the current module
112
                if (strlen($strTable))
113
                {
114
                        if (!in_array($strTable, (array) $arrModule['tables']))
115
                        {
116
                                $this->log('Table "' . $strTable . '" is not allowed in module "' . $module . '"', 'Backend getBackendModule()', TL_ERROR);
117
                                $this->redirect('typolight/main.php?act=error');
118
                        }
119
120
                        // Load the language and DCA file
121
                        $this->loadLanguageFile($strTable);
122
                        $this->loadDataContainer($strTable);
123
124
                        // Include all excluded fields which are allowed for the current user
125
                        if ($GLOBALS['TL_DCA'][$strTable]['fields'])
126
                        {
127
                                foreach ($GLOBALS['TL_DCA'][$strTable]['fields'] as $k=>$v)
128
                                {
129
                                        if ($v['exclude'])
130
                                        {
131
                                                if ($this->User->hasAccess($strTable.'::'.$k, 'alexf'))
132
                                                {
133
                                                        $GLOBALS['TL_DCA'][$strTable]['fields'][$k]['exclude'] = false;
134
                                                }
135
                                        }
136
                                }
137
                        }
138
139
                        // Fabricate a new data container object
140
                        if (!strlen($GLOBALS['TL_DCA'][$strTable]['config']['dataContainer']))
141
                        {
142
                                $this->log('Missing data container for table "' . $strTable . '"', 'Backend getBackendModule()', TL_ERROR);
143
                                trigger_error('Could not create a data container object', E_USER_ERROR);
144
                        }
145
146
                        $dataContainer = 'DC_' . $GLOBALS['TL_DCA'][$strTable]['config']['dataContainer'];
147
                        require(sprintf('%s/system/drivers/%s.php', TL_ROOT, $dataContainer));
148
149
                        $dc = new $dataContainer($strTable);
150
                }
151
152
                // AJAX request
153
                if ($this->Input->post('isAjax'))
154
                {
155
                        $this->objAjax->executePostActions($dc);
156
                }
157
158
                // Call module callback
159
                elseif ($this->classFileExists($arrModule['callback']))
160
                {
161
                        $objCallback = new $arrModule['callback']($dc);
162
                        $this->Template->main .= $objCallback->generate();
163
                }
164
165
                // Custom action (if key is not defined in config.php the default action will be called)
166
                elseif ($this->Input->get('key') && isset($arrModule[$this->Input->get('key')]))
167
                {
168
                        $objCallback = new $arrModule[$this->Input->get('key')][0]();
169
                        $this->Template->main .= $objCallback->$arrModule[$this->Input->get('key')][1]($dc, $strTable, $arrModule);
170
                }
171
172
                // Default action
173
                elseif (is_object($dc))
174
                {
175
                        $act = $this->Input->get('act');
176
177
                        if (!strlen($act) || $act == 'paste' || $act == 'select')
178
                        {
179
                                $act = ($dc instanceof listable) ? 'showAll' : 'edit';
180
                        }
181
182
                        switch ($act)
183
                        {
184
                                case 'delete':
185
                                case 'show':
186
                                case 'showAll':
187
                                case 'undo':
188
                                        if (!$dc instanceof listable)
189
                                        {
190
                                                $this->log('Data container ' . $strTable . ' is not listable', 'Backend getBackendModule()', TL_ERROR);
191
                                                trigger_error('The current data container is not listable', E_USER_ERROR);
192
                                        }
193
                                        break;
194
195
                                case 'create':
196
                                case 'cut':
197
                                case 'copy':
198
                                case 'move':
199
                                case 'edit':
200
                                        if (!$dc instanceof editable)
201
                                        {
202
                                                $this->log('Data container ' . $strTable . ' is not editable', 'Backend getBackendModule()', TL_ERROR);
203
                                                trigger_error('The current data container is not editable', E_USER_ERROR);
204
                                        }
205
                                        break;
206
                        }
207
208
                        return $dc->$act();
209
                }
210
211
                return null;
212
        }
213
214
215
        /**
216
         * Get all searchable pages and return them as array
217
         * @param integer
218
         * @param string
219
         * @return array
220
         */
221
        protected function findSearchablePages($pid=0, $domain='')
222
        {
223
                $time = time();
224
225
                // Get published pages
226
                $objPages = $this->Database->prepare("SELECT * FROM tl_page WHERE pid=? AND (start='' OR start<?) AND (stop='' OR stop>?) AND published=1 ORDER BY sorting")
227
                                                                   ->execute($pid, $time, $time);
228
229
                if ($objPages->numRows < 1)
230
                {
231
                        return array();
232
                }
233
234
                // Fallback domain
235
                if (!strlen($domain))
236
                {
237
                        $domain = $this->Environment->base;
238
                }
239
240
                $arrPages = array();
241
242
                // Recursively walk through all subpages
243
                while($objPages->next())
244
                {
245
                        // Set domain
246
                        if ($objPages->type == 'root')
247
                        {
248
                                if (strlen($objPages->dns))
249
                                {
250
                                        $domain = ($this->Environment->ssl ? 'https://' : 'http://') . $objPages->dns . TL_PATH . '/';
251
                                }
252
                                else
253
                                {
254
                                        $domain = $this->Environment->base;
255
                                }
256
                        }
257
258
                        // Add regular pages
259
                        elseif ($objPages->type == 'regular')
260
                        {
261
                                // Searchable and not protected
262
                                if (!$objPages->noSearch && (!$objPages->protected || $GLOBALS['TL_CONFIG']['indexProtected']))
263
                                {
264
                                        // Published
265
                                        if ($objPages->published && (!$objPages->start || $objPages->start < $time) && (!$objPages->stop || $objPages->stop > $time))
266
                                        {
267
                                                $arrPages[] = $domain . $this->generateFrontendUrl($objPages->row());
268
269
                                                // Get articles with teaser
270
                                                $objArticle = $this->Database->prepare("SELECT * FROM tl_article WHERE pid=? AND (start='' OR start<?) AND (stop='' OR stop>?) AND published=1 AND showTeaser=1 ORDER BY sorting")
271
                                                                                                         ->execute($objPages->id, $time, $time);
272
273
                                                while ($objArticle->next())
274
                                                {
275
                                                        $arrPages[] = $domain . $this->generateFrontendUrl($objPages->row(), '/articles/' . ((strlen($objArticle->alias) && !$GLOBALS['TL_CONFIG']['disableAlias']) ? $objArticle->alias : $objArticle->id));
276
                                                }
277
                                        }
278
                                }
279
                        }
280
281
                        // Get subpages
282
                        if ((!$objPages->protected || $GLOBALS['TL_CONFIG']['indexProtected']) && ($arrSubpages = $this->findSearchablePages($objPages->id, $domain)) != false)
283
                        {
284
                                $arrPages = array_merge($arrPages, $arrSubpages);
285
                        }
286
                }
287
288
                return $arrPages;
289
        }
290
291
292
        /**
293
         * Get all allowed pages and return them as string
294
         * @return string
295
         */
296
        public function createPageList()
297
        {
298
                $this->import('BackendUser', 'User');
299
300
                if ($this->User->isAdmin)
301
                {
302
                        return $this->doCreatePageList();
303
                }
304
305
                $return = '';
306
                $processed = array();
307
308
                foreach ($this->eliminateNestedPages($this->User->pagemounts) as $page)
309
                {
310
                        $objPage = $this->getPageDetails($page);
311
312
                        // Root page mounted
313
                        if ($objPage->type == 'root')
314
                        {
315
                                $title = $objPage->title;
316
                                $start = $objPage->id;
317
                        }
318
319
                        // Regular page mounted
320
                        else
321
                        {
322
                                $title = $objPage->rootTitle;
323
                                $start = $objPage->rootId;
324
                        }
325
326
                        // Do not process twice
327
                        if (in_array($start, $processed))
328
                        {
329
                                continue;
330
                        }
331
332
                        $processed[] = $start;
333
                        $return .= '<optgroup label="' . $title . '">' . $this->doCreatePageList($start) . '</optgroup>';
334
                }
335
336
                return $return;
337
        }
338
339
340
        /**
341
         * Recursively get all allowed pages and return them as string
342
         * @param integer
343
         * @param integer
344
         * @return string
345
         */
346
        protected function doCreatePageList($intId=0, $level=-1)
347
        {
348
                $objPages = $this->Database->prepare("SELECT id, title, type, dns FROM tl_page WHERE pid=? ORDER BY sorting")
349
                                                                   ->execute($intId);
350
351
                if ($objPages->numRows < 1)
352
                {
353
                        return '';
354
                }
355
356
                ++$level;
357
                $strOptions = '';
358
359
                while ($objPages->next())
360
                {
361
                        if ($objPages->type == 'root')
362
                        {
363
                                // Skip websites that run under a different domain
364
                                if ($objPages->dns && $objPages->dns != $this->Environment->host && $objPages->dns != 'www.' . $this->Environment->host)
365
                                {
366
                                        continue;
367
                                }
368
369
                                $strOptions .= '<optgroup label="' . $objPages->title . '">';
370
                                $strOptions .= $this->doCreatePageList($objPages->id, -1);
371
                                $strOptions .= '</optgroup>';
372
                        }
373
                        else
374
                        {
375
                                $strOptions .= sprintf('<option value="{{link_url::%s}}"%s>%s%s</option>', $objPages->id, (('{{link_url::' . $objPages->id . '}}' == $this->Input->get('value')) ? ' selected="selected"' : ''), str_repeat(" &nbsp; &nbsp; ", $level), specialchars($objPages->title));
376
                                $strOptions .= $this->doCreatePageList($objPages->id, $level);
377
                        }
378
                }
379
380
                return $strOptions;
381
        }
382
383
384
        /**
385
         * Get all allowed files and return them as string
386
         * @param boolean
387
         * @param boolean
388
         * @return string
389
         */
390
        public function createFileList($blnFilterImages=false, $filemount=false)
391
        {
392
                $this->import('BackendUser', 'User');
393
394
                if ($this->User->isAdmin)
395
                {
396
                        return $this->doCreateFileList($GLOBALS['TL_CONFIG']['uploadPath'], -1, $blnFilterImages);
397
                }
398
399
                $return = '';
400
                $processed = array();
401
402
                // Set custom filemount
403
                if ($filemount)
404
                {
405
                        $this->User->filemounts = array($filemount);
406
                }
407
408
                // Limit nodes to the filemounts of the user
409
                foreach ($this->eliminateNestedPaths($this->User->filemounts) as $path)
410
                {
411
                        if (in_array($path, $processed))
412
                        {
413
                                continue;
414
                        }
415
416
                        $processed[] = $path;
417
                        $return .= $this->doCreateFileList($path, -1, $blnFilterImages);
418
                }
419
420
                return $return;
421
        }
422
423
424
        /**
425
         * Recursively get all allowed files and return them as string
426
         * @param integer
427
         * @param integer
428
         * @param boolean
429
         * @return string
430
         */
431
        protected function doCreateFileList($strFolder=null, $level=-1, $blnFilterImages=false)
432
        {
433
                $arrPages = scan(TL_ROOT . '/' . $strFolder);
434
435
                // Empty folder
436
                if (count($arrPages) < 1)
437
                {
438
                        return '';
439
                }
440
441
                // Protected folder
442
                if (array_search('.htaccess', $arrPages) !== false)
443
                {
444
                        return '';
445
                }
446
447
                ++$level;
448
                $strFolders = '';
449
                $strFiles = '';
450
451
                // Recursively list all files and folders
452
                foreach ($arrPages as $strFile)
453
                {
454
                        if (substr($strFile, 0, 1) == '.')
455
                        {
456
                                continue;
457
                        }
458
459
                        // Folders
460
                        if (is_dir(TL_ROOT . '/' . $strFolder . '/' . $strFile))
461
                        {
462
                                $strFolders .=  $this->doCreateFileList($strFolder . '/' . $strFile, $level, $blnFilterImages);
463
                        }
464
465
                        // Filter images
466
                        elseif ($blnFilterImages && !preg_match('/\.gif$|\.jpg$|\.jpeg$|\.png$/i', $strFile))
467
                        {
468
                                continue;
469
                        }
470
471
                        // Files
472
                        elseif ($strFile != 'meta.txt')
473
                        {
474
                                $strFiles .= sprintf('<option value="%s"%s>%s</option>', $strFolder . '/' . $strFile, (($strFolder . '/' . $strFile == $this->Input->get('value')) ? ' selected="selected"' : ''), specialchars($strFile));
475
                        }
476
                }
477
478
                if (strlen($strFiles))
479
                {
480
                        return '<optgroup label="' . specialchars($strFolder) . '">' . $strFiles . $strFolders . '</optgroup>';
481
                }
482
483
                return $strFiles . $strFolders;
484
        }
485
}
486
487
?>