root/trunk/wifidog-auth/wifidog/classes/MainUI.php @ 1130

Revision 1130, 20.5 KB (checked in by benoitg, 7 years ago)
  • MainUI.php: Allow displaying any object with getUserUI directly as content.
  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
Line 
1<?php
2
3
4/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
5
6// +-------------------------------------------------------------------+
7// | WiFiDog Authentication Server                                     |
8// | =============================                                     |
9// |                                                                   |
10// | The WiFiDog Authentication Server is part of the WiFiDog captive  |
11// | portal suite.                                                     |
12// +-------------------------------------------------------------------+
13// | PHP version 5 required.                                           |
14// +-------------------------------------------------------------------+
15// | Homepage:     http://www.wifidog.org/                             |
16// | Source Forge: http://sourceforge.net/projects/wifidog/            |
17// +-------------------------------------------------------------------+
18// | This program is free software; you can redistribute it and/or     |
19// | modify it under the terms of the GNU General Public License as    |
20// | published by the Free Software Foundation; either version 2 of    |
21// | the License, or (at your option) any later version.               |
22// |                                                                   |
23// | This program is distributed in the hope that it will be useful,   |
24// | but WITHOUT ANY WARRANTY; without even the implied warranty of    |
25// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     |
26// | GNU General Public License for more details.                      |
27// |                                                                   |
28// | You should have received a copy of the GNU General Public License |
29// | along with this program; if not, contact:                         |
30// |                                                                   |
31// | Free Software Foundation           Voice:  +1-617-542-5942        |
32// | 59 Temple Place - Suite 330        Fax:    +1-617-542-2652        |
33// | Boston, MA  02111-1307,  USA       gnu@gnu.org                    |
34// |                                                                   |
35// +-------------------------------------------------------------------+
36
37/**
38 * @package    WiFiDogAuthServer
39 * @author     Benoit Grégoire <bock@step.polymtl.ca>
40 * @copyright  2005-2006 Benoit Grégoire, Technologies Coeus inc.
41 * @version    Subversion $Id$
42 * @link       http://www.wifidog.org/
43 */
44
45/**
46 * @internal We put a call to validate_schema() here so it systematically called
47 * from any UI page, but not from any machine readable pages
48 */
49require_once ('include/schema_validate.php');
50validate_schema();
51
52/**
53 * If the database doesn't get cleaned up by a cron job, we'll do now
54 */
55if (CONF_USE_CRON_FOR_DB_CLEANUP == false)
56{
57        garbage_collect();
58}
59
60/**
61 * Load required file
62 */
63require_once ('include/common_interface.php');
64
65/**
66 * Singleton class for managing headers, footers, stylesheet, etc.
67 *
68 * @package    WiFiDogAuthServer
69 * @author     Benoit Grégoire <bock@step.polymtl.ca>
70 * @copyright  2005-2006 Benoit Grégoire, Technologies Coeus inc.
71 */
72class MainUI
73{
74/** holder for the singleton */
75        private static $object;
76
77        /**
78        * Content to be displayed the page
79        *
80        * @var array
81        * @access private
82        */
83        private $_contentDisplayArray;
84
85        /**
86        * Content to be displayed on the page, before ordering
87        *
88        * @var array
89        * @access private
90        */
91        private $_contentArray;
92
93        /**
94         * Object for Smarty class
95         *
96         * @var object
97         * @access private
98         */
99        private $smarty;
100
101        /**
102         * Title of HTML page
103         *
104         * @var string
105         * @access private
106         */
107        private $title;
108        /**
109         * Additional class of the <body> of the HTML page
110         */
111        private $_pageName;
112
113        /** list of URLs to stylesheet to be included */
114        private $stylesheetUrlArray=array();
115
116        /**
117         * Headers of HTML page
118         *
119         * @var private
120         * @access private
121         */
122        private $_htmlHeaders;
123
124        /**
125         * Defines if tool section of HTML page is enabled or not
126         *
127         * @var bool
128         * @access private
129         */
130        private $_toolSectionEnabled = true;
131
132        /**
133         * Scripts for the footer
134         *
135         * @var array
136         * @access private
137         */
138        private $_footerScripts = array ();
139
140        private $_shrinkLeftArea = false;
141    /**
142     * Get the MainUI object
143     * @return object The MainUI object
144     */
145    public static function getObject() {
146        if (self::$object==null)
147        {
148                self::$object=new self();
149        }
150        return self::$object;
151    }
152        /**
153         * Contructor
154         *
155         * @return void
156         *
157         * @access public
158         */
159        private function __construct()
160        {
161                $db = AbstractDb::getObject();
162                // Init Smarty
163                $this->smarty = SmartyWifidog::getObject();
164
165                // Set default title
166                $this->title = Network :: getCurrentNetwork()->getName() . ' ' . _("authentication server");
167                // Init the content array
168                $current_content_sql = "SELECT display_area FROM content_available_display_areas\n";
169                $rows = array ();
170                $db->execSql($current_content_sql, $rows, false);
171                foreach ($rows as $row)
172                {
173                        $this->_contentDisplayArray[$row['display_area']] = '';
174                }
175        }
176
177        /**
178         * Add content to a structural area of the page
179         *
180         * @param string $display_area Structural area where content is to be
181         * placed.  Must be one of the display aread defined in the
182         * content_available_display_areas table
183         *
184         * @param string $content Either a Content object (recommended) or raw HTML content to be added to the area
185         *
186         * @param integer $display_order_index The order in which the content should
187         * be displayed
188         *
189         * @return void
190         */
191        public function addContent($displayArea, $content, $displayOrderIndex = 1)
192        {
193                //echo "MainUI::addContent(): Debug: displayArea: $displayArea, displayOrderIndex: $displayOrderIndex, content: $content<br/>";
194                if (!isset ($this->_contentDisplayArray[$displayArea]))
195                {
196                        throw new exception(sprintf(_('%s is not a valid structural display area'), $displayArea));
197                }
198                $this->_contentArray[] = array (
199                        'display_area' => $displayArea,
200                        'display_order' => $displayOrderIndex,
201                        'content' => $content
202                );
203        }
204
205        /** Private compare function for sorting the _contentArray() */
206        private static function _contentArrayCmp($a, $b)
207        {
208                if ($a['display_order'] == $b['display_order'])
209                {
210                        return 0;
211                }
212                return ($a['display_order'] < $b['display_order']) ? -1 : 1;
213        }
214
215        /** Main processing function do generate the final content.
216         * It will successively call prepareGetUserUI() on all content objects,
217         * and then getUserUI() on all objects.  Note that the point of calling
218         * prepareGetUserUI is to allow that function to call methods of MainUI
219         * (such ans changing headers, etc.).  However, please note that you should not
220         * call MainUI::addContent() from prepareGetUserUI, as prepareGetUserUI() wouldn't
221         * in turn get called on objects added this way.
222         * Orders the content and put it in the _contentDisplayArray array
223         *
224         * @return void
225         */
226        private function generateDisplayContent()
227        {
228                //pretty_print_r($this->_contentArray);
229                usort($this->_contentArray, array (
230                        $this,
231                        "_contentArrayCmp"
232                ));
233               
234                //Fist pass (preparation pass)
235                foreach ($this->_contentArray as $content_fragment)
236                {
237                        $content=$content_fragment['content'];
238
239                if (method_exists($content,'prepareGetUserUI'))
240                        {
241                            //echo "<h1>prepareGetUserUI on ".$content->getId()."</h1>";
242                                $content->prepareGetUserUI();
243                        }
244                }
245                foreach ($this->_contentArray as $content_fragment)
246                {
247                    $content=$content_fragment['content'];
248                        if (is_object($content))
249                {
250                        if (method_exists($content,'getUserUI'))
251                        {
252                                $this->_contentDisplayArray[$content_fragment['display_area']] .= $content->getUserUI();
253                        }
254                        else
255                        {
256                        throw new exception ("Object must implement getUserUI");
257                        }
258                }
259                else
260                {
261                    $this->_contentDisplayArray[$content_fragment['display_area']] .= $content;
262                }
263                }
264
265        }
266
267        /**
268         * Add the content marked "everywhere" from both the current node and the
269         * current network.
270         *
271         * @return void
272         */
273        private function addEverywhereContent()
274        {
275                $db = AbstractDb::getObject();
276                // Get all network content and node "everywhere" content
277                $content_rows = null;
278                $network_id = $db->escapeString(Network :: getCurrentNetwork()->getId());
279                $sql_network = "(SELECT content_id, display_area, display_order, subscribe_timestamp FROM network_has_content WHERE network_id='$network_id'  AND display_page='everywhere') ";
280                $node = Node :: getCurrentNode();
281                $sql_node = null;
282                if ($node)
283                {
284                        // Get all node content
285                        $node_id = $db->escapeString($node->getId());
286                        $sql_node = "UNION (SELECT content_id, display_area, display_order, subscribe_timestamp FROM node_has_content WHERE node_id='$node_id'  AND display_page='everywhere')";
287                }
288                $sql = "SELECT * FROM ($sql_network $sql_node) AS content_everywhere ORDER BY display_area, display_order, subscribe_timestamp DESC";
289
290                $db->execSql($sql, $content_rows, false);
291                if ($content_rows)
292                {
293                        foreach ($content_rows as $content_row)
294                        {
295                                $content = Content :: getObject($content_row['content_id']);
296                                if ($content->isDisplayableAt($node))
297                                {
298                                        $this->addContent($content_row['display_area'], $content, $content_row['display_order']);
299                                }
300                        }
301                }
302
303        }
304
305        /**
306        * Check if the tool section is enabled
307        *
308        * @return bool True or false
309        *
310        * @access public
311        */
312        public function isToolSectionEnabled()
313        {
314                return $this->_toolSectionEnabled;
315        }
316
317        /**
318         * Check if the tool section is enabled
319         *
320         * @return bool True or false
321         *
322         * @access public
323         */
324        public function setToolSectionEnabled($status)
325        {
326                $this->_toolSectionEnabled = $status;
327        }
328
329        /**
330         * Set the title of the HTML page
331         *
332         * @param string $title_string Title of the HTML page
333         *
334         * @return void
335         *
336         * @access public
337         */
338        public function setTitle($title_string)
339        {
340                $this->title = $title_string;
341        }
342
343        public function shrinkLeftArea()
344        {
345                $this->_shrinkLeftArea = true;
346        }
347
348        /**
349         * Set the class name of the <body> of the resulting page.
350         *
351         * @param string $page_name_string The page name of the resulting page.  Must have no spaces.  ex:  portal, login, userprofile, etc.)
352         *
353         * @return void
354         *
355         * @access public
356         */
357        public function setPageName($page_name_string)
358        {
359                $this->_pageName = $page_name_string;
360        }
361
362        /**
363        * Add content at the very end of the <body>.
364        *
365        * This is NOT meant to add footers or other display content, it is meant
366        * to add <script></script> tag pairs that have to be executed only once
367        * the page is loaded.
368        *
369        * @param string $script A piece of script surrounded by
370        *                       <script></script> tags.
371        *
372        * @return void
373        *
374        * @access public
375        */
376        public function addFooterScript($script)
377        {
378                $this->_footerScripts[] = $script;
379        }
380
381        /**
382         * Set the HTML page headers
383         *
384         * @param string $headers_string HTML page headers
385         *
386         * @return void
387         *
388         * @access public
389         */
390        public function setHtmlHeader($headers_string)
391        {
392                $this->_htmlHeaders = $headers_string;
393        }
394       
395        /**
396         * Add a stylesheet URL to the main page
397         *
398         * @param string Stylesheet URL
399         *
400         * @return void
401         *
402         * @access public
403         */
404        public function appendStylesheetURL($stylesheet_url)
405        {
406            //Note:  using the URL as value AND key will remove duplicate while keeping the stylesheet inclusion order, because of the way foreach is implemented in PHP
407                $this->stylesheetUrlArray[$stylesheet_url] = $stylesheet_url;
408        }
409        /**
410         * Set the section to be displayed in the tool pane
411         *
412         * @param string $section Section to be displayed:
413         *                          + ADMIN for administration tool pane
414         *
415         * @return string HTML code of tool pane
416         *
417         * @access public
418         */
419        public function setToolSection($section)
420        {
421                // Init ALL smarty SWITCH values
422                $this->smarty->assign('sectionADMIN', false);
423
424                switch ($section)
425                {
426                        case "ADMIN" :
427                                // Set section of Smarty template
428                                $this->smarty->assign('sectionADMIN', true);
429
430                                // Get information about user
431                                $_currentUser = User :: getCurrentUser();
432
433                                        // Init values
434                                        $_sqlAdditionalWhere = "";
435
436                                        // Init ALL smarty values
437                                        User :: assignSmartyValues($this->smarty, $_currentUser);
438                                        $this->smarty->assign('formAction', "");
439                                        $this->smarty->assign('nodeUI', "");
440                                        $this->smarty->assign('networkUI', "");
441
442                                        /*
443                                         * If the user is super admin OR owner of at least one node
444                                         * show the node menu
445                                         */
446                                        if ($_currentUser && ($_currentUser->isSuperAdmin() || $_currentUser->isOwner()))
447                                        {
448                                                // Assign the action URL for the form
449                                                $this->smarty->assign('formAction', GENERIC_OBJECT_ADMIN_ABS_HREF);
450
451                                                /*
452                                                 * If current user is a owner the SQL query must be changed
453                                                 * to return his nodes only
454                                                 */
455                                                if (!$_currentUser->isSuperAdmin())
456                                                {
457                                                        $_sqlAdditionalWhere = "AND node_id IN (SELECT node_id from node_stakeholders WHERE is_owner = true AND user_id='" . $_currentUser->getId() . "')";
458                                                }
459
460                                                // Provide node select control to the template
461                                                $this->smarty->assign('nodeUI', Node :: getSelectNodeUI('object_id', $_sqlAdditionalWhere));
462                                        }
463
464                                        // If the user is network admin show the network menu
465                                        if ($_currentUser && $_currentUser->isSuperAdmin())
466                                        {
467                                                // Provide network select control to the template
468                                                $this->smarty->assign('networkUI', Network :: getSelectNetworkUI('object_id'));
469                                        }
470
471                                        // Compile HTML code
472                                        $_html = $this->smarty->fetch("templates/classes/MainUI_ToolSection.tpl");
473                                break;
474
475                        default :
476                                $_html = _("Unknown section:") . $section;
477                                break;
478                }
479
480                $this->addContent('left_area_middle', $_html);
481        }
482
483        /**
484         * Get the content to be displayed in the tool pane
485         *
486         * @return string HTML markup
487         *
488         * @access private
489         */
490        private function getToolContent()
491        {
492               
493                $session = Session::getObject();
494                global $AVAIL_LOCALE_ARRAY;
495
496                // Init values
497                $_html = "";
498                $_gwId = null;
499                $_gwAddress = null;
500                $_gwPort = null;
501                $_selected = "";
502                $_languageChooser = array ();
503
504                // Init ALL smarty SWITCH values
505                $this->smarty->assign('sectionSTART', false);
506                $this->smarty->assign('sectionLOGIN', false);
507
508                // Set section of Smarty template
509                $this->smarty->assign('sectionSTART', true);
510
511                // Get information about user
512                $_currentUser = User :: getCurrentUser();
513
514                User :: assignSmartyValues($this->smarty, $_currentUser);
515
516                $this->smarty->assign('logoutParameters', "");
517                $this->smarty->assign('loginParameters', "");
518                $this->smarty->assign('formAction', "");
519                $this->smarty->assign('toolContent', "");
520                $this->smarty->assign('accountInformation', "");
521                $this->smarty->assign('techSupportInformation', "");
522                $this->smarty->assign('shrinkLeftArea', $this->_shrinkLeftArea);
523
524                // Provide Smarty with information about the network
525                Network :: assignSmartyValues($this->smarty);
526
527                /*
528                 * Provide Smarty information about the user's login/logout status
529                 */
530
531                if ($_currentUser != null)
532                {
533                        // User is logged in
534
535                        // Detect gateway information
536                        $_gwId = $session->get(SESS_GW_ID_VAR);
537                        $_gwAddress = $session->get(SESS_GW_ADDRESS_VAR);
538                        $_gwPort = $session->get(SESS_GW_PORT_VAR);
539
540                        // If gateway information could be detected tell them Smarty
541                        if ($_gwId && $_gwAddress && $_gwPort)
542                        {
543                                $this->smarty->assign('logoutParameters', "&amp;gw_id=" . $_gwId . "&amp;gw_address=" . $_gwAddress . "&amp;gw_port=" . $_gwPort);
544                        }
545                }
546                else
547                {
548                        // Detect gateway information
549                        $_gwId = !empty ($_REQUEST['gw_id']) ? $_REQUEST['gw_id'] : $session->get(SESS_GW_ID_VAR);
550                        $_gwAddress = !empty ($_REQUEST['gw_address']) ? $_REQUEST['gw_address'] : $session->get(SESS_GW_ADDRESS_VAR);
551                        $_gwPort = !empty ($_REQUEST['gw_port']) ? $_REQUEST['gw_port'] : $session->get(SESS_GW_PORT_VAR);
552
553                        // If gateway information could be detected tell them Smarty
554                        if (!empty ($_gwId) && !empty ($_gwAddress) && !empty ($_gwPort))
555                        {
556                                $this->smarty->assign('loginParameters', "?gw_id=" . $_gwId . "&amp;gw_address=" . $_gwAddress . "&amp;gw_port=" . $_gwPort);
557                        }
558                }
559
560                /*
561                 * Provide Smarty information for the language chooser
562                 */
563
564                // Assign the action URL for the form
565                $this->smarty->assign('formAction', $_SERVER['REQUEST_URI']);
566
567                foreach ($AVAIL_LOCALE_ARRAY as $_langIds => $_langNames)
568                {
569                        if (Locale :: getCurrentLocale()->getId() == $_langIds)
570                        {
571                                $_selected = ' selected="selected"';
572                        }
573                        else
574                        {
575                                $_selected = "";
576                        }
577
578                        $_languageChooser[] = '<option label="' . $_langNames . '" value="' . $_langIds . '"' . $_selected . '>' . $_langNames . '</option>';
579                }
580
581                // Provide Smarty all available languages
582                $this->smarty->assign('languageChooser', $_languageChooser);
583
584                // Compile HTML code
585                $_html = $this->smarty->fetch("templates/classes/MainUI_ToolContent.tpl");
586
587                return $_html;
588        }
589
590        /**
591         * Display the main page
592         *
593         * @return void
594         *
595         * @access public
596         * @internal Uses a few request parameters to display debug information.
597         * If $_REQUEST['debug_request'] is present, it will print out the
598         * $_REQUEST array at the top of the page.
599         */
600        public function display()
601        {
602        $db=AbstractDb::getObject();
603                // Init values
604                // Asign base CSS and theme pack CSS stylesheet
605                $this->appendStylesheetURL(BASE_THEME_URL . STYLESHEET_NAME);
606                $networkThemePack = Network :: getCurrentNetwork()->getThemePack();
607                if ($networkThemePack) {
608                                $this->appendStylesheetURL($networkThemePack->getStylesheetUrl());
609                }
610               
611                //Handle content (must be done before headers and anything else is handled)
612                /*
613                 * Build tool pane if it has been enabled
614                 */
615                if ($this->isToolSectionEnabled())
616                {
617                        $this->addContent('left_area_top', $this->getToolContent());
618                }
619                $this->addEverywhereContent();
620                $this->generateDisplayContent();
621
622                // Init ALL smarty values
623                $this->smarty->assign('htmlHeaders', "");
624                // $this->smarty->assign('isSuperAdmin', false);
625                // $this->smarty->assign('isOwner', false);
626                $this->smarty->assign('debugRequested', false);
627                $this->smarty->assign('debugOutput', "");
628                $this->smarty->assign('footerScripts', array ());
629
630                // Add HTML headers
631                $this->smarty->assign('htmlHeaders', $this->_htmlHeaders);
632
633                // Asign title
634                $this->smarty->assign('title', $this->title);
635
636                // Asign CSS class for body
637                $this->smarty->assign('page_name', $this->_pageName);
638               
639                $this->smarty->assign('stylesheetUrlArray', $this->stylesheetUrlArray);
640
641                /*
642                 * Allow super admin to display debug output if requested by using
643                 * $_REQUEST['debug_request']
644                 */
645
646                // Get information about user
647                User :: assignSmartyValues($this->smarty);
648
649                // Provide footer scripts to Smarty
650                $this->smarty->assign('footerScripts', $this->_footerScripts);
651
652        // Add SQL queries log (must be done manually here at the very end to catch everything)
653        if(defined("LOG_SQL_QUERIES") && LOG_SQL_QUERIES == true)
654            $this->_contentDisplayArray['page_footer'] .= $db->getSqlQueriesLog();
655       
656        // Provide the content array to Smarty
657        $this->smarty->assign('contentDisplayArray', $this->_contentDisplayArray);
658           
659                // Compile HTML code and output it
660                $this->smarty->display("templates/classes/MainUI_Display.tpl");
661        }
662
663        /**
664         * Display a generic error message
665         *
666         * @param string $errmsg                  The error message to be displayed
667         * @param bool   $show_tech_support_email Defines wether to show the link of
668         *                                        the tech-support
669         *
670         * @return void
671         *
672         * @access public
673         */
674        function displayError($errmsg, $show_tech_support_email = true)
675        {
676                // Init ALL smarty values
677                $this->smarty->assign("error", "");
678                $this->smarty->assign("show_tech_support_email", false);
679                $this->smarty->assign("tech_support_email", "");
680
681                // Define needed error content
682                $this->smarty->assign("error", $errmsg);
683
684                if ($show_tech_support_email)
685                {
686                        $this->smarty->assign("show_tech_support_email", true);
687                        $this->smarty->assign("tech_support_email", Network :: getCurrentNetwork()->getTechSupportEmail());
688                }
689
690                /*
691                 * Output the error message
692                 */
693                $_html = $this->smarty->fetch("templates/sites/error.tpl");
694
695                $this->addContent('page_header', $_html);
696                $this->display();
697        }
698
699        static public function redirect($redirect_url, $redirect_to_title = null, $timeout = 60)
700        {
701                if (!$redirect_to_title)
702                {
703                        $network = Network :: getCurrentNetwork();
704                        $redirect_to_title = $network ? sprintf(_("%s Login"), $network->getName()) : _("Login");
705                }
706
707                header("Location: $redirect_url");
708                echo "<html>\n" . "<head><meta http-equiv='Refresh' content='$timeout; URL=$redirect_url'/></head>\n" . "<body>\n" . "<noscript>\n" . "<span style='display:none;'>\n" . "<h1>" . $redirect_to_title . "</h1>\n" . sprintf(_("Click <a href='%s'>here</a> to continue"), $redirect_url) . "<br/>\n" . _("The transfer from secure login back to regular http may cause a warning.") . "\n" . "</span>\n" . "</noscript>\n" . "</body>\n" . "</html>\n";
709                exit;
710        }
711}
712
713/*
714 * Local variables:
715 * tab-width: 4
716 * c-basic-offset: 4
717 * c-hanging-comment-ender-p: nil
718 * End:
719 */
Note: See TracBrowser for help on using the browser.