Project

General

Profile

1 1839 darkviper
<?php
2
3
/**
4
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
 */
19
/**
20
 * Description of PageTree
21
 *
22
 * @category     WbACP
23
 * @package      WbACP_Pages
24
 * @author       Werner v.d. Decken <wkl@isteam.de>
25
 * @copyright    Werner v.d. Decken <wkl@isteam.de>
26
 * @license      http://www.gnu.org/licenses/gpl.html   GPL License
27
 * @version      1.0.0
28
 * @revision     $Revision$
29
 * @link         $HeadURL$
30
 * @lastmodified $Date$
31
 * @since        file added on 2012-12-21
32
 */
33
34
class a_pages_PageTree
35
{
36
/** @var array language definitions */
37
	private $_TEXT     = null;
38
/** @var array language definitions */
39
	private $_MESSAGE  = null;
40
/** @var array language definitions */
41
	private $_HEADING  = null;
42
/** @var object instance of the application object */
43
	private $_oApp     = null;
44
/** @var object instance of the database object */
45
	private $_oDb      = null;
46
/** @var array holds several values from the application global scope */
47
	private $_aReg     = array();
48
/** @var string full HTML formattet list of pages */
49
	private $_sOutput         = '';
50
/** @var integer number of all reachable pages */
51
	private $_iPagesTotal     = 0;
52
/** @var integer number of all writeable pages */
53
	private $_iPagesWriteable = 0;
54
/** @var integer index for toggle background color of the list */
55
	private $_iLineColor      = 0;
56
/** @var array entries to build a select list for parents */
57
	private $_aParentList     = array();
58
/** @var integer count all executed database requests passing all iterations. */
59
	private $_queries = 0;
60
/**
61
 * constructor used to import some application constants and objects
62
 */
63
	public function __construct()
64
	{
65
		// import global vars and objects
66
		$this->_wbAdaptor();
67
	}
68
/**
69
 * parse the page tree and return
70
 * @return type
71
 */
72
	public function parseTree() {
73
		return $this->_createTree();
74
	}
75
/**
76
 *  parse the page tree and print it out
77
 */
78
	public function displayTree() {
79
		echo $this->parseTree();
80
	}
81
/**
82
 * total number of found pages which are visible for actual user
83
 * @return integer
84
 */
85
	public function getTotalPages() {
86
		return $this->_iPagesTotal;
87
	}
88
/**
89
 * number of found pages which are writable for actual user
90
 * @return integer
91
 */
92
	public function getWriteablePages() {
93
		return $this->_iPagesWriteable;
94
	}
95
/**
96
 * a list with all possible parent pages
97
 * @return array
98
 */
99
	public function getParentList() {
100
		if(!$this->_sOutput) {
101
			$this->parseTree();
102
		}
103
		return $this->_aParentList;
104
	}
105
/**
106
 * used to import some WB-constants and objects
107
 */
108
	private function _wbAdaptor()
109
	{
110
		$this->_TEXT        = $GLOBALS['TEXT'];
111
		$this->_MESSAGE     = $GLOBALS['MESSAGE'];
112
		$this->_HEADING     = $GLOBALS['HEADING'];
113
		$this->_oApp        = $GLOBALS['admin'];
114
		$this->_oDb         = WbDatabase::getInstance();
115
		$this->_aReg['PAGE_TRASH']       = PAGE_TRASH;
116
		$this->_aReg['PAGE_LEVEL_LIMIT'] = PAGE_LEVEL_LIMIT;
117
		$this->_aReg['MANAGE_SECTIONS']  = MANAGE_SECTIONS;
118
		$this->_aReg['WB_URL']           = WB_URL;
119
		$this->_aReg['WB_REL']           = WB_REL;
120
		$this->_aReg['ACP_REL']          = ADMIN_REL;
121
		$this->_aReg['THEME_REL']        = THEME_REL;
122
		$this->_aReg['TABLE_PREFIX']     = TABLE_PREFIX;
123
	}
124
/**
125
 * create a page tree as a well formatted, unordered list
126
 * @return string the whoole list
127
 */
128
	private function _createTree()
129
	{
130
		// compose the complete list
131
		$sOutput = ''
132
		// build the head
133
		      . $this->_Tabs(0 , true).'<div class="pages_list">'.PHP_EOL
134
		      . $this->_Tabs(1).'<table>'.PHP_EOL
135
		      . $this->_Tabs(1).'<tbody>'.PHP_EOL
136
		      . $this->_Tabs(1).'<tr class="pages_list_header">'.PHP_EOL
137
		      . $this->_Tabs(1).'<th class="header_list_menu_title">'.$this->_TEXT['VISIBILITY'].
138
		                        ' / '.$this->_TEXT['MENU_TITLE'].':</th>'.PHP_EOL
139
		      . $this->_Tabs(0).'<th class="header_list_page_title">'.$this->_TEXT['PAGE_TITLE'].
140
		                        '</th>'.PHP_EOL
141
		      . $this->_Tabs(0).'<th class="header_list_page_id">PID</th>'.PHP_EOL
142
		      . $this->_Tabs(0).'<th class="header_list_actions">'.$this->_TEXT['ACTIONS'].
143
		                        ':</th>'.PHP_EOL
144
		      . $this->_Tabs(0).'<th class="list_page_id">&nbsp;</th>'.PHP_EOL
145
		      . $this->_Tabs(-1).'</tr>'.PHP_EOL
146
		      . $this->_Tabs(-1).'</tbody>'.PHP_EOL
147
		      . $this->_Tabs(-1).'</table>'.PHP_EOL
148
		// generate the page lines
149
		      . $this->_IterateTree()
150
		// build the footer
151
		      . $this->_Tabs(-1).'</div>'.PHP_EOL;
152
		;
153
		$this->_sOutput = $sOutput;
154
		return $sOutput;
155
	}
156
/**
157
 * Create a string of multiple TABs to prettify the HTML-output
158
 * ingrease the number of TABs with a positive and degrease with an negative Value.
159
 * '0' means: do not change the value. Or set an absolute number using $bRelative=false
160
 * @staticvar int $iTabLevel
161
 * @param integer $iTabsDiv number of TABs to add/sub
162
 * @param bool $bRelative false if should be set to absolute value
163
 * @return string
164
 */
165
	private function _Tabs($iTabsDiv = 0, $bRelative = true)
166
	{
167
		static $iTabLevel = 0;
168
		$iTabLevel = ($bRelative ? $iTabLevel + $iTabsDiv : $iTabsDiv);
169
		$iTabLevel += ($iTabLevel < 0 ? 0 - $iTabLevel : $iTabsDiv);
170
		return str_repeat("\t", $iTabLevel);
171
	}
172
/**
173
 * compose the needed SQL statement
174
 * @param integer $iParentKey
175
 * @return string SQL statement
176
 */
177
	private function _makeSql($iParentKey = 0)
178
	{
179
		if($this->_aReg['PAGE_TRASH'] != 'inline') {
180
			$sUseTrash = ' AND `visibility`!=\'deleted\'';
181
		}else { $sUseTrash = ''; }
182
		$sql = 'SELECT ( SELECT COUNT(*) '
183
		     .          'FROM `'.$this->_aReg['TABLE_PREFIX'].'pages` `x` '
184
		     .          'WHERE x.`parent`=p.`page_id`'
185
		     .        ') `children`, '
186
		     .        's.`module`, MAX(s.`publ_start` + s.`publ_end`) published, p.`link`, '
187
		     .        '(SELECT MAX(`position`) FROM `'.$this->_aReg['TABLE_PREFIX'].'pages` '
188
		     .        'WHERE `parent`='.$iParentKey.') max_position, '
189
		     .        '0 min_position, '
190
		     .        'p.`position`, '
191
		     .        'p.`page_id`, p.`parent`, p.`level`, p.`language`, p.`admin_groups`, '
192
		     .        'p.`admin_users`, p.`viewing_groups`, p.`viewing_users`, p.`visibility`, '
193
		     .        'p.`menu_title`, p.`page_title`, p.`page_trail` '
194
		     . 'FROM `'.$this->_aReg['TABLE_PREFIX'].'pages` p '
195
		     .    'INNER JOIN `'.$this->_aReg['TABLE_PREFIX'].'sections` s '
196
		     .    'ON p.`page_id`=s.`page_id` '
197
		     . 'WHERE `parent`='.$iParentKey.$sUseTrash.' '
198
		     . 'GROUP BY p.`page_id` '
199
		     . 'ORDER BY p.`position` ASC';
200
		return $sql;
201
	}
202
/**
203
 * iterate through all nodes which having subnodes
204
 * @param integer $iParent
205
 * @return string all of the item lines
206
 */
207
	private function _IterateTree($iParent = 0)
208
	{
209
		$sOutput = '';
210
		// Get page list from database
211
		if(($oPages = $this->_oDb->query($this->_makeSql($iParent))))
212
		{
213
			$this->_queries++;
214
			// output block-header
215
			$sOutput .= $this->_Tabs(0).'<ul id="p'.$iParent.'" class="page_list"';
216
			if(!$iParent) {
217
				$sOutput .= ' style="display: block;"';
218
			}else {
219
			// show block depending from Cookies
220
				if (isset ($_COOKIE['p'.$iParent]) && $_COOKIE['p'.$iParent] == '1') {
221
					$sOutput .= ' style="display: block;"';
222
				}
223
			}
224
			$sOutput .= '>'.PHP_EOL;
225
			$iMinPosition = 1;
226
			while($aPage = $oPages->fetchRow(MYSQL_ASSOC))
227
			{ // iterate through the current branch
228
				$aPage['min_position'] = ($aPage['position'] < $iMinPosition ? $aPage['position'] : $iMinPosition);
229
				$this->_iLineColor = $this->_iPagesTotal++ % 2;
230
				$aPage['iswriteable'] = false;
231
				if( $this->_oApp->ami_group_member($aPage['admin_users']) ||
232
					$this->_oApp->is_group_match($this->_oApp->get_groups_id(), $aPage['admin_groups']))
233
				{
234
					if(($aPage['visibility'] == 'deleted' && $this->_aReg['PAGE_TRASH'] == 'inline') ||
235
					   ($aPage['visibility'] != 'deleted'))
236
					{
237
						$aPage['iswriteable'] = true;
238
						$this->_iPagesWriteable++;
239
					}
240
				} else {
241
					if($aPage['visibility'] == 'private') { continue; }
242
				}
243
				// add this item to the secondary list of parents
244
				$this->_addToParentList($aPage);
245
				$sOutput .= $this->_createListItem($aPage);
246
			}
247
			$sOutput .= $this->_Tabs(-1).'</ul>'.PHP_EOL;
248
		}
249
		return $sOutput;
250
	}
251
/**
252
 * formating the given page object for output
253
 * @param type $aPage
254
 * @return string
255
 */
256
	private function _createListItem($aPage)
257
	{
258
	// output the current item
259
	// --- HEADER ------------------------------------------------------------------------
260
		$sOutput  = $this->_Tabs(0).'<li class="p'.$aPage['parent'].'">'.PHP_EOL
261
		          . $this->_Tabs(1).'<table class="pages_view">'.PHP_EOL
262
		          . $this->_Tabs(1).'<tbody>'.PHP_EOL
263
		          . $this->_Tabs(1).'<tr class="row_'.$this->_iLineColor.'">'.PHP_EOL;
264
	// --- TAB 1 --- (expand/collapse) ---------------------------------------------------
265
		$sOutput .= $this->_Tabs(1).'<td valign="middle" width="20" style="padding-left: '
266
		          . (int)($aPage['level']*20).'px;">';
267
		if((bool)$aPage['children']) {
268
			$sOutput .= '<a href="javascript:toggle_visibility(\'p'.$aPage['page_id'].'\');" '
269
			          . 'title="'.$this->_TEXT['EXPAND'].'/'.$this->_TEXT['COLLAPSE'].'">'
270
			          . '<span><img src="'.$this->_aReg['THEME_REL'].'/images/'
271
			          . ( ((isset($_COOKIE['p'.$aPage['page_id']])
272
						  && $_COOKIE['p'.$aPage['page_id']] == '1') ? 'minus' : 'plus')
273
						)
274
			          . '_16.png" onclick="toggle_plus_minus(\''.$aPage['page_id'].'\');" '
275
			          . 'name="plus_minus_'.$aPage['page_id'].'" alt="+" /></span></a>';
276
		}else {
277
			$sOutput .= '&nbsp;';
278
		}
279
		$sOutput .= '</td>'.PHP_EOL;
280
	// --- TAB 2 --- (menu title) --------------------------------------------------------
281
		switch($aPage['visibility']):
282
			case 'private':
283
				$sIcon = 'private_16.png';
284
				$sText = $this->_TEXT['PRIVATE'];
285
				break;
286
			case 'registered':
287
				$sIcon = 'keys_16.png';
288
				$sText = $this->_TEXT['REGISTERED'];
289
				break;
290
			case 'hidden':
291
				$sIcon = 'hidden_16.png';
292
				$sText = $this->_TEXT['HIDDEN'];
293
				break;
294
			case 'none':
295
				$sIcon = 'none_16.png';
296
				$sText = $this->_TEXT['NONE'];
297
				break;
298
			case 'deleted':
299
				$sIcon = 'deleted_16.png';
300
				$sText = $this->_TEXT['DELETED'];
301
				break;
302
			default: // public
303
				$sIcon = 'visible_16.png';
304
				$sText = $this->_TEXT['PUBLIC'];
305
				break;
306
		endswitch;
307
		$sOutput .= $this->_Tabs(0).'<td class="list_menu_title">';
308
		if($this->_oApp->get_permission('pages_modify') && $aPage['iswriteable']) {
309
			$sOutput .= '<a href="'.$this->_aReg['ACP_REL'].'/pages/modify.php?page_id='
310
			          . $aPage['page_id'].'" title="'.$this->_TEXT['MODIFY'].'">';
311
		}
312
		$sOutput .= '<img src="'.$this->_aReg['THEME_REL'].'/images/'.$sIcon.'" '
313
		          . 'alt="'.$this->_TEXT['VISIBILITY'].': '.$sText.'" class="page_list_rights" />';
314
		if($this->_oApp->get_permission('pages_modify') && $aPage['iswriteable']) {
315
			$sOutput .= '<span class="modify_link">'.$aPage['menu_title'].'</span></a>';
316
		}else {
317
			$sOutput .=  '<span class="bold grey">'.$aPage['menu_title'].'</span>';
318
		}
319
		$sOutput .= '</td>'.PHP_EOL;
320
	// --- TAB 3 --- (page title) --------------------------------------------------------
321
		$sOutput .= $this->_Tabs(0).'<td class="list_page_title">'.$aPage['page_title'].'</td>'.PHP_EOL;
322
	// --- TAB 4 --- (page ID) -----------------------------------------------------------
323
		$sOutput .= $this->_Tabs(0).'<td class="list_page_id right">'.$aPage['page_id'].'</td>'.PHP_EOL;
324
	// --- TAB 5 --- (show this page in new window) --------------------------------------
325
		$sOutput .= $this->_Tabs(0).'<td class="list_actions">';
326
		if($aPage['visibility'] != 'deleted' && $aPage['visibility'] != 'none') {
327
			$sPageLink = $this->_aReg['WB_REL'].preg_replace(
328
			                                 '/^'.preg_quote($this->_aReg['WB_URL'], '/').'/siU',
329
			                                 '',
330
			                                 $this->_oApp->page_link($aPage['link'])
331
			                                );
332
			$sOutput .= '<a href="'.$sPageLink.'" target="_blank" title="'.$this->_TEXT['VIEW']
333
			          . '"><img src="'.$this->_aReg['THEME_REL'].'/images/view_16.png" alt="'
334
			          . $this->_TEXT['VIEW'].'" /></a>';
335
		}else {
336
			$sOutput .= '<img src="'.$this->_aReg['THEME_REL'].'/images/blank_16.gif" alt=" " />';
337
		}
338
		$sOutput .= '</td>'.PHP_EOL;
339
340
	// --- TAB 6 --- (edit settings) -----------------------------------------------------
341
		$sOutput .= $this->_Tabs(0).'<td class="list_actions">';
342
		if($aPage['visibility'] != 'deleted') {
343
			if($this->_oApp->get_permission('pages_settings') && $aPage['iswriteable']) {
344
				$sOutput .= '<a href="'.$this->_aReg['ACP_REL'].'/pages/settings.php?page_id='
345
				          . $aPage['page_id'].'" title="'.$this->_TEXT['SETTINGS'].'">'
346
				          . '<img src="'.$this->_aReg['THEME_REL'].'/images/modify_16.png" alt="'
347
				          . $this->_TEXT['SETTINGS'].'" /></a>';
348
			}
349
		}else {
350
			$sOutput .= '<a href="'.$this->_aReg['ACP_REL'].'/pages/restore.php?page_id='.$aPage['page_id'].'" '
351
			          . 'title="'.$this->_TEXT['RESTORE'].'"><img src="'.$this->_aReg['THEME_REL']
352
			          . '/images/restore_16.png" alt="'.$this->_TEXT['RESTORE'].'" /></a>';
353
		}
354
		$sOutput .= '</td>'.PHP_EOL;
355
356
	// --- TAB 7 --- (edit sections) -----------------------------------------------------
357
		$sOutput .= $this->_Tabs(0).'<td class="list_actions">';
358
		if( $this->_aReg['MANAGE_SECTIONS'] && $this->_oApp->get_permission('pages_add') && $aPage['iswriteable'] ) {
359
			$file = $this->_oApp->page_is_active($aPage) ? "clock_16.png" : "clock_red_16.png";
360
			$file = ($aPage['published'] && $aPage['module'] != 'menu_link') ? $file : 'noclock_16.png';
361
			$sOutput .= '<a href="'.$this->_aReg['ACP_REL'].'/pages/sections.php?page_id='
362
			          . $aPage['page_id'].'" title="'.$this->_HEADING['MANAGE_SECTIONS'].'">'
363
			          . '<img src="'.$this->_aReg['THEME_REL'].'/images/'.$file.'" alt="'
364
			          . $this->_HEADING['MANAGE_SECTIONS'].'" /></a>';
365
		}else {
366
			$sOutput .= '<img src="'.$this->_aReg['THEME_REL'].'/images/blank_16.gif" alt=" " />';
367
		}
368
		$sOutput .= '</td>'.PHP_EOL;
369
370
	// --- TAB 8 --- (move up) -----------------------------------------------------------
371
		$sOutput .= $this->_Tabs(0).'<td class="list_actions">';
372
		if($aPage['position'] > $aPage['min_position']) {
373
			if($aPage['visibility'] != 'deleted') {
374
				if($this->_oApp->get_permission('pages_settings') && $aPage['iswriteable']) {
375
					$sOutput .= '<a href="'.$this->_aReg['ACP_REL'].'/pages/move_up.php?page_id='
376
					          . $aPage['page_id'].'" title="'.$this->_TEXT['MOVE_UP']
377
					          . '"><img src="'.$this->_aReg['THEME_REL'].'/images/up_16.png" alt="'
378
					          . $this->_TEXT['MOVE_UP'].'" /></a>';
379
				}
380
			}
381
		}
382
		$sOutput .= '</td>'.PHP_EOL;
383
384
	// --- TAB 9 --- (move down) ---------------------------------------------------------
385
		$sOutput .= $this->_Tabs(0).'<td class="list_actions">';
386
		if($aPage['position'] < $aPage['max_position']) {
387
			if($aPage['visibility'] != 'deleted') {
388
				if($this->_oApp->get_permission('pages_settings') && $aPage['iswriteable']) {
389
					$sOutput .= '<a href="'.$this->_aReg['ACP_REL'].'/pages/move_down.php?page_id='
390
					          . $aPage['page_id'].'" title="'.$this->_TEXT['MOVE_DOWN']
391
					          . '"><img src="'.$this->_aReg['THEME_REL'].'/images/down_16.png" alt="'
392
					          . $this->_TEXT['MOVE_DOWN'].'" /></a>';
393
				}
394
			}
395
		}
396
		$sOutput .= '</td>'.PHP_EOL;
397
398
	// --- TAB 10 --- (delete page) ------------------------------------------------------
399
		$sOutput .= $this->_Tabs(0).'<td class="list_actions">';
400
		if($this->_oApp->get_permission('pages_delete') && $aPage['iswriteable']) {
401
			$sOutput .= '<a href="javascript:confirm_link(pages_delete_confirm+\'?\',\''
402
			          . $this->_aReg['ACP_REL'].'/pages/delete.php?page_id='
403
			          . $this->_oApp->getIDKEY($aPage['page_id']).'\');" title="'
404
			          . $this->_TEXT['DELETE'].'"><img src="'.$this->_aReg['THEME_REL']
405
			          . '/images/delete_16.png" alt="'.$this->_TEXT['DELETE'].'" /></a>';
406
		}else {
407
			$sOutput .= '<img src="'.$this->_aReg['THEME_REL'].'/images/blank_16.gif" alt=" " />';
408
		}
409
		$sOutput .= '</td>'.PHP_EOL;
410
411
	// --- TAB 11 --- (add child page) ---------------------------------------------------
412
		$sOutput .= $this->_Tabs(0).'<td class="list_actions">';
413
		if(
414
			$this->_oApp->get_permission('pages_add')
415
			&& $aPage['iswriteable']
416
			&& ($aPage['visibility'] != 'deleted')
417
			&& $aPage['level'] < ($this->_aReg['PAGE_LEVEL_LIMIT'] - 1)
418
		  )
419
		{
420
			$sOutput .= '<a href="javascript:add_child_page(\''.$aPage['page_id'].'\');" '
421
			          . 'title="'.$this->_HEADING['ADD_CHILD_PAGE'].'"><img src="'
422
			          . $this->_aReg['THEME_REL'].'/images/siteadd.png" name="addpage_'.$aPage['page_id']
423
			          . '" alt="'.$this->_HEADING['ADD_CHILD_PAGE'].'" /></a>';
424
		}else {
425
			$sOutput .= '&nbsp;';
426
		}
427
		$sOutput .= '</td>'.PHP_EOL;
428
	// --- TAB 12 --- (show language) ----------------------------------------------------
429
		$sOutput .= $this->_Tabs(0).'<td class="list_page_id center">'.$aPage['language'].'</td>'.PHP_EOL;
430
	// --- FOOTER ------------------------------------------------------------------------
431
		$sOutput .= $this->_Tabs(-1).'</tr>'.PHP_EOL
432
		          . $this->_Tabs(-1).'</tbody>'.PHP_EOL
433
		          . $this->_Tabs(-1).'</table>'.PHP_EOL;
434
	// if there children, iterate through this children now
435
		if((bool)$aPage['children']) {
436
			$sOutput .= $this->_IterateTree($aPage['page_id']);
437
		}
438
		$sOutput .= $this->_Tabs(-1).'</li>'.PHP_EOL;
439
		return $sOutput;
440
	} // end of method _createListItem
441
/**
442
 * build a list of possible parent pages
443
 * @param array $aPage
444
 */
445
	private function _addToParentList(array $aPage)
446
	{
447
		if( ($aPage['level'] < ($this->_aReg['PAGE_LEVEL_LIMIT'] - 1))
448
			&& $aPage['iswriteable']
449
			&& ($aPage['visibility'] != 'deleted')
450
			&& $this->_oApp->get_permission('pages_add') )
451
		{
452
			$aNewEntry = array();
453
			$aNewEntry['ID']             = $aPage['page_id'];
454
			$aNewEntry['TITLE']          = $aPage['menu_title'];
455
			$aNewEntry['DISABLED']       = ($aPage['iswriteable'] ? 0 : 1);
456
			$aNewEntry['PARENT']         = $aPage['parent'];
457
			$aNewEntry['FLAG_ROOT_ICON'] = '';
458
			$aNewEntry['LEVEL']          = $aPage['level'];
459
			$aNewEntry['LANGUAGE']       = $aPage['language'];
460
			$this->_aParentList[]        = $aNewEntry;
461
		}
462
	}
463
464
} // end of class PageTree