root/trunk/wifidog-auth/wifidog/classes/Network.php @ 1312

Revision 1312, 66.9 KB (checked in by benoitg, 5 years ago)
  • Node.php: Fix bug in setCurrentNode() reported by Vacio
  • 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/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4
5// +-------------------------------------------------------------------+
6// | WiFiDog Authentication Server                                     |
7// | =============================                                     |
8// |                                                                   |
9// | The WiFiDog Authentication Server is part of the WiFiDog captive  |
10// | portal suite.                                                     |
11// +-------------------------------------------------------------------+
12// | PHP version 5 required.                                           |
13// +-------------------------------------------------------------------+
14// | Homepage:     http://www.wifidog.org/                             |
15// | Source Forge: http://sourceforge.net/projects/wifidog/            |
16// +-------------------------------------------------------------------+
17// | This program is free software; you can redistribute it and/or     |
18// | modify it under the terms of the GNU General Public License as    |
19// | published by the Free Software Foundation; either version 2 of    |
20// | the License, or (at your option) any later version.               |
21// |                                                                   |
22// | This program is distributed in the hope that it will be useful,   |
23// | but WITHOUT ANY WARRANTY; without even the implied warranty of    |
24// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     |
25// | GNU General Public License for more details.                      |
26// |                                                                   |
27// | You should have received a copy of the GNU General Public License |
28// | along with this program; if not, contact:                         |
29// |                                                                   |
30// | Free Software Foundation           Voice:  +1-617-542-5942        |
31// | 59 Temple Place - Suite 330        Fax:    +1-617-542-2652        |
32// | Boston, MA  02111-1307,  USA       gnu@gnu.org                    |
33// |                                                                   |
34// +-------------------------------------------------------------------+
35
36/**
37 * @package    WiFiDogAuthServer
38 * @author     Benoit Grégoire <bock@step.polymtl.ca>
39 * @author     Max Horváth <max.horvath@freenet.de>
40 * @copyright  2005-2006 Benoit Grégoire, Technologies Coeus inc.
41 * @copyright  2006 Max Horváth, Horvath Web Consulting
42 * @version    Subversion $Id$
43 * @link       http://www.wifidog.org/
44 */
45
46/**
47 * Load required classes
48 */
49require_once('classes/GenericDataObject.php');
50require_once('classes/Content.php');
51require_once('classes/User.php');
52require_once('classes/Node.php');
53require_once('classes/GisPoint.php');
54require_once('classes/Cache.php');
55require_once('classes/ThemePack.php');
56
57
58/**
59 * Abstract a Network.
60 *
61 * A network is an administrative entity with it's own users, nodes and authenticator.
62 *
63 * @package    WiFiDogAuthServer
64 * @author     Benoit Grégoire <bock@step.polymtl.ca>
65 * @author     Max Horváth <max.horvath@freenet.de>
66 * @copyright  2005-2006 Benoit Grégoire, Technologies Coeus inc.
67 * @copyright  2006 Max Horváth, Horvath Web Consulting
68 */
69class Network extends GenericDataObject
70{
71    /** Object cache for the object factory (getObject())*/
72    private static $instanceArray = array();
73
74    /**
75     * Get an instance of the object
76     *
77     * @param string $id The object id
78     *
79     * @return mixed The Content object, or null if there was an error
80     *               (an exception is also thrown)
81     *
82     * @see GenericObject
83     * @static
84     * @access public
85     */
86    public static function &getObject($id)
87    {
88        if(!isset(self::$instanceArray[$id]))
89        {
90            self::$instanceArray[$id] = new self($id);
91        }
92        return self::$instanceArray[$id];
93    }
94
95    /**
96     * Get all the Networks configured on this server
97     *
98     * @return array An array of Network objects.  The default network is
99     *               returned first
100     *
101     * @static
102     * @access public
103     */
104    public static function getAllNetworks()
105    {
106        $retval = array ();
107        $db = AbstractDb::getObject();
108        $sql = "SELECT network_id FROM networks";
109        $network_rows = null;
110        $db->execSql($sql, $network_rows, false);
111        if ($network_rows == null) {
112            throw new Exception(_("Network::getAllNetworks:  Fatal error: No networks in the database!"));
113        }
114        foreach ($network_rows as $network_row) {
115            $retval[] = self::getObject($network_row['network_id']);
116        }
117        return $retval;
118    }
119
120    /**
121     * Get the default network
122     *
123     * @return object A Network object, NEVER returns null.
124     *
125     * @static
126     * @access public
127     */
128    public static function getDefaultNetwork()
129    {
130        $retval = null;
131        $vhost = VirtualHost :: getCurrentVirtualHost();
132        if ($vhost == null) {
133            $vhost = VirtualHost :: getDefaultVirtualHost();
134        }
135        return $vhost->getDefaultNetwork();
136    }
137
138    /**
139     * Get the current network for which the portal is displayed or to which a
140     * user is physically connected.
141     *
142     * @param bool $real_network_only NOT IMPLEMENTED YET true or false.  If
143     *                                true, the real physical network where the
144     *                                user is connected is returned, and
145     *                                the node set by setCurrentNode is ignored.
146     *
147     * @return objetc A Network object, NEVER returns null.
148     *
149     * @static
150     * @access public
151     */
152    public static function getCurrentNetwork($real_network_only = false)
153    {
154        $retval = null;
155        $current_node = Node :: getCurrentNode();
156
157        if ($current_node != null) {
158            $retval = $current_node->getNetwork();
159        } else {
160            $retval = Network :: getDefaultNetwork();
161        }
162
163        return $retval;
164    }
165
166    /**
167     * Create a new Network object in the database
168     *
169     * @param string $network_id The network id of the new network.  If absent,
170     *                           will be assigned a guid.
171     *
172     * @return mixed The newly created object, or null if there was an error
173     *
174     * @see GenericObject
175     * @static
176     * @access public
177     */
178    public static function createNewObject($network_id = null)
179    {
180        $db = AbstractDb::getObject();
181        if (empty ($network_id)) {
182            $network_id = get_guid();
183        }
184        $network_id = $db->escapeString($network_id);
185
186        $sql = "INSERT INTO networks (network_id, network_authenticator_class) VALUES ('$network_id', 'AuthenticatorLocalUser')";
187
188        if (!$db->execSqlUpdate($sql, false)) {
189            throw new Exception(_('Unable to insert the new network in the database!'));
190        }
191        $object = self::getObject($network_id);
192        return $object;
193
194    }
195
196     /**
197     * Get an interface to pick an object of this class
198     *
199     * If there is only one server available, no interface is actually shown
200     *
201     * @param string $user_prefix         A identifier provided by the
202     *                                    programmer to recognise it's generated
203     *                                    html form
204     *  @param string $userData=null Array of contextual data optionally sent to the method.
205     *  The function must still function if none of it is present.
206     *
207     * This method understands:
208     *  $userData['preSelectedObject'] An optional Object of this class to be selected.
209     *  $userData['additionalWhere'] Additional SQL conditions for the
210     *                                    objects to select
211     *  $userData['allowEmpty'] boolean Allow not selecting any object
212     * @return string HTML markup
213
214     */
215    /**
216     * Get an interface to pick a network
217     *
218     * If there is only one network available, no interface is actually shown
219     *
220     * @param string $user_prefix          A identifier provided by the
221     *                                     programmer to recognise it's
222     *                                     generated html form
223     *
224     * @param string $userData=null Array of contextual data optionally sent to the method.
225     *  The function must still function if none of it is present.
226     *
227     * This method understands:
228     *  $userData['preSelectedObject'] An optional object to pre-select.
229     *  $userData['additionalWhere'] Additional SQL conditions for the
230     *                                    objects to select
231     *  $userData['allowEmpty'] boolean Allow not selecting any object
232     * @return string HTML markup
233
234     */
235    public static function getSelectUI($user_prefix, $userData=null)
236    {
237        $html = '';
238        $name = $user_prefix;
239        //pretty_print_r($userData);
240        !empty($userData['preSelectedObject'])?$selected_id=$userData['preSelectedObject']->getId():$selected_id=self::getDefaultNetwork()->getId();
241                !empty($userData['additionalWhere'])?$additional_where=$userData['additionalWhere']:$additional_where=null;
242                !empty($userData['allowEmpty'])?$allow_empty=$userData['allowEmpty']:$allow_empty=false;
243               
244        $db = AbstractDb::getObject();
245        $sql = "SELECT network_id, name FROM networks WHERE 1=1 $additional_where";
246        $network_rows = null;
247        $db->execSql($sql, $network_rows, false);
248        if ($network_rows == null) {
249            throw new Exception(_("Network::getAllNetworks:  Fatal error: No networks in the database!"));
250        }
251
252        $number_of_networks = count($network_rows);
253        if ($number_of_networks > 1) {
254            $i = 0;
255            foreach ($network_rows as $network_row) {
256                $tab[$i][0] = $network_row['network_id'];
257                $tab[$i][1] = $network_row['name'];
258                $i ++;
259            }
260            $html .= _("Network:")." \n";
261            $html .= FormSelectGenerator :: generateFromArray($tab, $selected_id, $name, null, $allow_empty);
262
263        } else {
264            foreach ($network_rows as $network_row) //iterates only once...
265            {
266                $html .= _("Network:")." \n";
267                $html .= " $network_row[name] ";
268                $html .= "<input type='hidden' name='$name' value='".htmlspecialchars($network_row['network_id'], ENT_QUOTES, 'UTF-8')."'>";
269            }
270        }
271
272        return $html;
273    }
274
275    /**
276     * Get the selected Network object.
277     *
278     * @param string $user_prefix A identifier provided by the programmer to
279     *                            recognise it's generated form
280     *
281     * @return mixed The network object or null
282
283     */
284    public static function processSelectUI($user_prefix)
285    {
286        $name = "{$user_prefix}";
287        if (!empty ($_REQUEST[$name])) {
288            return self::getObject($_REQUEST[$name]);
289        } else {
290            return null;
291        }
292    }
293
294    /**
295     * Get an interface to create a new network.
296     *
297     * @return string HTML markup
298     *
299     * @static
300     * @access public
301     */
302    public static function getCreateNewObjectUI()
303    {
304        // Init values
305        $html = '';
306
307        $html .= _("Create a new network with ID")." \n";
308        $name = "new_network_id";
309        $html .= "<input type='text' size='10' name='{$name}'>\n";
310
311        return $html;
312    }
313
314    /**
315     * Process the new object interface.
316     *
317     * Will return the new object if the user has the credentials and the form
318     * was fully filled.
319     *
320     * @return mixed The Network object or null if no new Network was created.
321     *
322     * @static
323     * @access public
324     */
325    public static function processCreateNewObjectUI()
326    {
327        // Init values
328        $retval = null;
329        $name = "new_network_id";
330
331        if (!empty($_REQUEST[$name])) {
332            $network_id = $_REQUEST[$name];
333
334            if ($network_id) {
335                try {
336                    if (!User::getCurrentUser()->DEPRECATEDisSuperAdmin()) {
337                        throw new Exception(_("Access denied"));
338                    }
339                } catch (Exception $e) {
340                    $ui = MainUI::getObject();
341                    $ui->displayError($e->getMessage(), false);
342                    exit;
343                }
344
345                $retval = self::createNewObject($network_id);
346            }
347        }
348
349        return $retval;
350    }
351
352    /**
353     * Constructor
354     *
355     * @param string $p_network_id
356     *
357     * @return void
358     *
359     * @access private
360     */
361    private function __construct($p_network_id)
362    {
363        $db = AbstractDb::getObject();
364        $network_id_str = $db->escapeString($p_network_id);
365        $sql = "SELECT *, EXTRACT(EPOCH FROM validation_grace_time) as validation_grace_time_seconds FROM networks WHERE network_id='$network_id_str'";
366        $row = null;
367        $db->execSqlUniqueRes($sql, $row, false);
368        if ($row == null) {
369            throw new Exception("The network with id $network_id_str could not be found in the database");
370        }
371        $this->_row = $row;
372        $this->_id = $p_network_id;
373    }
374
375    public function __toString()
376    {
377        return $this->getName();
378    }
379
380    /**
381     * Retreives the network name
382     *
383     * @return string The id
384     *
385     * @access public
386     */
387    public function getTechSupportEmail()
388    {
389        return $this->_row['tech_support_email'];
390    }
391
392    /**
393     * Set the network's tech support and information email address
394     *
395     * @param string $value The new value
396     *
397     * @return bool True on success, false on failure
398     *
399     * @access public
400     */
401    public function setTechSupportEmail($value)
402    {
403        // Init values
404        $retval = true;
405
406        if ($value != $this->getName()) {
407            $db = AbstractDb::getObject();
408            $value = $db->escapeString($value);
409            $retval = $db->execSqlUpdate("UPDATE networks SET tech_support_email = '{$value}' WHERE network_id = '{$this->getId()}'", false);
410            $this->refresh();
411        }
412
413        return $retval;
414    }
415
416    /**
417     * Retrieves the network name
418     *
419     * @return string A string
420     *
421     * @access public
422     */
423    public function getName()
424    {
425        return $this->_row['name'];
426    }
427
428    /**
429     * Set the network's name
430     *
431     * @param string $value The new value
432     *
433     * @return bool True on success, false on failure
434     *
435     * @access public
436     */
437    public function setName($value)
438    {
439        // Init values
440        $retval = true;
441
442        if ($value != $this->getName()) {
443            $db = AbstractDb::getObject();
444            $value = $db->escapeString($value);
445            $retval = $db->execSqlUpdate("UPDATE networks SET name = '{$value}' WHERE network_id = '{$this->getId()}'", false);
446            $this->refresh();
447        }
448
449        return $retval;
450    }
451
452    /**
453     * Retrieves the network's theme pack
454     *
455     * @return mixed ThemePack or null
456     *
457     * @access public
458     */
459    public function getThemePack()
460    {
461        if (!empty ($this->_row['theme_pack'])) {
462            return ThemePack::getObject($this->_row['theme_pack']);
463        } else {
464            return null;
465        }
466    }
467
468    /**
469     * Set the network's name
470     *
471     * @param string $value The new ThemePack, or null
472     *
473     * @return bool True on success, false on failure
474     *
475     * @access public
476     */
477    public function setThemePack($value)
478    {
479        // Init values
480        $retval = true;
481
482        if ($value != $this->getThemePack()) {
483            $db = AbstractDb::getObject();
484            empty($value)?$value="NULL":$value="'".$db->escapeString($value->getId())."'";
485            $retval = $db->execSqlUpdate("UPDATE networks SET theme_pack = {$value} WHERE network_id = '{$this->getId()}'", false);
486            $this->refresh();
487        }
488
489        return $retval;
490    }
491
492    /**
493     * Retrieves the network's creation date
494     *
495     * @return string Network's creation date
496     *
497     * @access public
498     */
499    public function getCreationDate()
500    {
501        return $this->_row['creation_date'];
502    }
503
504    /**
505     * Set the network's creation date
506     *
507     * @param string $value The new creation date
508     *
509     * @return bool True on success, false on failure
510     */
511    public function setCreationDate($value)
512    {
513
514        $db = AbstractDb::getObject();
515
516        // Init values
517        $_retVal = true;
518
519        if ($value != $this->getCreationDate()) {
520            $value = $db->escapeString($value);
521            $_retVal = $db->execSqlUpdate("UPDATE networks SET creation_date = '{$value}' WHERE network_id = '{$this->getId()}'", false);
522            $this->refresh();
523        }
524
525        return $_retVal;
526    }
527
528    /**
529     * Retreives the network's homepage url
530     *
531     * @return string The id
532     *
533     * @access public
534     */
535    public function getWebSiteURL()
536    {
537        return $this->_row['homepage_url'];
538    }
539
540    /**
541     * Set the network's homepage url
542     *
543     * @param string $value The new value
544     *
545     * @return bool True on success, false on failure
546     *
547     * @access public
548     */
549    public function setWebSiteUrl($value)
550    {
551        // Init values
552        $retval = true;
553
554        if ($value != $this->getName()) {
555            $db = AbstractDb::getObject();
556            $value = $db->escapeString($value);
557            $retval = $db->execSqlUpdate("UPDATE networks SET homepage_url = '{$value}' WHERE network_id = '{$this->getId()}'", false);
558            $this->refresh();
559        }
560
561        return $retval;
562    }
563
564    /**
565     * Retreives the network's authenticator's class name.
566     *
567     * @return string Name of authenticator's class
568     */
569    public function getAuthenticatorClassName()
570    {
571        return $this->_row['network_authenticator_class'];
572    }
573
574    /**
575     * Set the network's authenticator's class.
576     *
577     * The subclass of Authenticator to be used for user authentication
578     * (ex: AuthenticatorRadius)
579     *
580     * @param string $value The class name of a  subclass of Authenticator
581     *
582     * @return bool True on success, false on failure
583     */
584    public function setAuthenticatorClassName($value)
585    {
586
587        $db = AbstractDb::getObject();
588
589        // Init values
590        $retval = true;
591
592        if ($value != $this->getAuthenticatorClassName()) {
593            $value = $db->escapeString($value);
594            $retval = $db->execSqlUpdate("UPDATE networks SET network_authenticator_class = '{$value}' WHERE network_id = '{$this->getId()}'", false);
595            $this->refresh();
596        }
597
598        return $retval;
599    }
600
601    /**
602     * Retreives the authenticator's parameters
603     *
604     * @return string Authenticator's parameters
605     */
606    public function getAuthenticatorConstructorParams()
607    {
608        return $this->_row['network_authenticator_params'];
609    }
610
611    /**
612     * The explicit parameters to be passed to the authenticator's constructor
613     * (ex: 'my_network_id', '192.168.0.11', 1812, 1813, 'secret_key',
614     * 'CHAP_MD5')
615     *
616     * @param string $value The new value
617     *
618     * @return bool True on success, false on failure
619     */
620    public function setAuthenticatorConstructorParams($value)
621    {
622
623        $db = AbstractDb::getObject();
624
625        // init values
626        $retval = true;
627
628        if ($value != $this->getAuthenticatorConstructorParams()) {
629            $value = $db->escapeString($value);
630            $retval = $db->execSqlUpdate("UPDATE networks SET network_authenticator_params = '{$value}' WHERE network_id = '{$this->getId()}'", false);
631            $this->refresh();
632        }
633
634        return $retval;
635    }
636
637    /**
638     * Get the Authenticator object for this network
639     *
640     * @return object A subclass of Authenticator
641     */
642    public function getAuthenticator()
643    {
644        require_once ('classes/Authenticator.php');
645
646        // Include only the authenticator we are about to use
647        require_once ("classes/Authenticators/".$this->_row['network_authenticator_class'].".php");
648
649        if (strpos($this->_row['network_authenticator_params'], ';') != false) {
650            throw new Exception("Network::getAuthenticator(): Security error: The parameters passed to the constructor of the authenticator are potentially unsafe");
651        }
652
653        return call_user_func_array(array (new ReflectionClass($this->_row['network_authenticator_class']), 'newInstance'), explode(",", str_replace(array ("'", '"'), "", str_replace(", ", ",", $this->_row['network_authenticator_params']))));
654    }
655
656    /**
657     * Get the list of available Authenticators on the system
658     *
659     * @return array An array of class names
660
661     */
662    public static function getAvailableAuthenticators()
663    {
664        // Init values
665        $_authenticators = array ();
666        $_useCache = false;
667        $_cachedData = null;
668
669        // Create new cache object with a lifetime of one week
670        $_cache = new Cache("AuthenticatorClasses", "ClassFileCaches", 604800);
671
672        // Check if caching has been enabled.
673        if ($_cache->isCachingEnabled) {
674            $_cachedData = $_cache->getCachedData("mixed");
675
676            if ($_cachedData) {
677                // Return cached data.
678                $_useCache = true;
679                $_authenticators = $_cachedData;
680            }
681        }
682
683        if (!$_useCache) {
684            $_dir = WIFIDOG_ABS_FILE_PATH."classes/Authenticators";
685            $_dirHandle = @ opendir($_dir);
686
687            if ($_dirHandle) {
688                // Loop over the directory
689                while (false !== ($_filename = readdir($_dirHandle))) {
690                    // Loop through sub-directories of Content
691                    if ($_filename != '.' && $_filename != '..') {
692                        $_matches = null;
693
694                        if (preg_match("/^(.*)\.php$/", $_filename, $_matches) > 0) {
695                            // Only add files containing a corresponding Authenticator class
696                            if (is_file("{$_dir}/{$_matches[0]}")) {
697                                $_authenticators[] = $_matches[1];
698                            }
699                        }
700                    }
701                }
702
703                closedir($_dirHandle);
704            }
705            else {
706                throw new Exception(_('Unable to open directory ').$_dir);
707            }
708
709            // Sort the result array
710            sort($_authenticators);
711
712            // Check if caching has been enabled.
713            if ($_cache->isCachingEnabled) {
714                // Save results into cache, because it wasn't saved into cache before.
715                $_cache->saveCachedData($_authenticators, "mixed");
716            }
717        }
718
719        return $_authenticators;
720    }
721
722    /**
723     * Get an interface to pick an Authenticator
724     *
725     * @param string $user_prefix                A identifier provided by the
726     *                                           programmer to recognise it's
727     *                                           generated html form
728     * @param string $pre_selected_authenticator The Authenticator to be
729     *                                           pre-selected in the form object
730     *
731     * @return string HTML markup
732
733     */
734    public static function getSelectAuthenticator($user_prefix, $pre_selected_authenticator = null)
735    {
736
737        $db = AbstractDb::getObject();
738
739        // Init values
740        $_authenticators = array ();
741
742        foreach (self :: getAvailableAuthenticators() as $_authenticator) {
743            $_authenticators[] = array ($_authenticator, $_authenticator);
744        }
745
746        $_name = $user_prefix;
747
748        if ($pre_selected_authenticator) {
749            $_selectedID = $pre_selected_authenticator;
750        }
751        else {
752            $_selectedID = null;
753        }
754
755        $_html = FormSelectGenerator :: generateFromArray($_authenticators, $_selectedID, $_name, null, false);
756
757        return $_html;
758    }
759
760    /**
761     * Is the network the default network?
762     *
763     * @return bool True or false
764     *
765     * @access public
766     */
767    public function isDefaultNetwork()
768    {
769        (self::getDefaultNetwork()->getId() == $this->getId()) ? $retval = true : $retval = false;
770        return $retval;
771    }
772
773    /**
774     * Set as the default network.
775     *
776     * The can only be one default network, so this method will unset
777     * is_default_network for all other network
778     *
779     * @return bool True on success, false on failure
780     *
781     * @access public
782     */
783    public function setAsDefaultNetwork()
784    {
785        // Init values
786        $retval = true;
787
788        if (!$this->isDefaultNetwork()) {
789            $db = AbstractDb::getObject();
790            $sql = "UPDATE networks SET is_default_network = FALSE;\n";
791            $sql .= "UPDATE networks SET is_default_network = TRUE WHERE network_id = '{$this->getId()}';\n";
792            $retval = $db->execSqlUpdate($sql, false);
793            $this->refresh();
794        }
795
796        return $retval;
797    }
798
799    /**
800     * Retreives the network's validation grace period
801     *
802     * @return int Network's validation grace period in seconds
803     *
804     * @access public
805     */
806    public function getValidationGraceTime()
807    {
808        return $this->_row['validation_grace_time_seconds'];
809    }
810
811    /**
812     * Set the network's validation grace period in seconds.
813     *
814     * A new user is granted Internet access for this period check his email
815     * and validate his account.
816     *
817     * @param int $value The new value
818     *
819     * @return bool True on success, false on failure
820     *
821     * @access public
822     */
823    public function setValidationGraceTime($value)
824    {
825        // Init values
826        $retval = true;
827
828        if ($value != $this->getValidationGraceTime()) {
829            $db = AbstractDb::getObject();
830            $value = $db->escapeString($value);
831            $retval = $db->execSqlUpdate("UPDATE networks SET validation_grace_time = '{$value} seconds' WHERE network_id = '{$this->getId()}'", false);
832            $this->refresh();
833        }
834
835        return $retval;
836    }
837
838    /**
839     * Retreives the FROM address of the validation email
840     *
841     * @return string A string
842     *
843     * @access public
844     */
845    public function getValidationEmailFromAddress()
846    {
847        return $this->_row['validation_email_from_address'];
848    }
849
850    /**
851     * Set the FROM address of the validation email
852     *
853     * @param string $value The new value
854     *
855     * @return bool True on success, false on failure
856     *
857     * @access public
858     */
859    public function setValidationEmailFromAddress($value)
860    {
861        // Init values
862        $retval = true;
863
864        if ($value != $this->getValidationEmailFromAddress()) {
865            $db = AbstractDb::getObject();
866            $value = $db->escapeString($value);
867            $retval = $db->execSqlUpdate("UPDATE networks SET validation_email_from_address = '{$value}' WHERE network_id = '{$this->getId()}'", false);
868            $this->refresh();
869        }
870
871        return $retval;
872    }
873
874    /**
875     * Can an account be connected more than once at the same time?
876     *
877     * @return bool True or false
878     *
879     * @access public
880     */
881    public function getMultipleLoginAllowed()
882    {
883        return ($this->_row['allow_multiple_login'] == 't') ? true : false;
884    }
885
886    /**
887     * Set if a account be connected more than once at the same time
888     *
889     * @param bool $value The new value, true or false
890     *
891     * @return bool true on success, false on failure
892     *
893     * @access public
894     */
895    public function setMultipleLoginAllowed($value)
896    {
897        // Init values
898        $retval = true;
899
900        if ($value != $this->getMultipleLoginAllowed()) {
901            $db = AbstractDb::getObject();
902            $value ? $value = 'TRUE' : $value = 'FALSE';
903            $retval = $db->execSqlUpdate("UPDATE networks SET allow_multiple_login = {$value} WHERE network_id = '{$this->getId()}'", false);
904            $this->refresh();
905        }
906
907        return $retval;
908    }
909
910    /**
911     * Are nodes allowed to be set as splash-only (no login)?
912     *
913     * @return bool True or false
914     *
915     * @access public
916     */
917    public function getSplashOnlyNodesAllowed()
918    {
919        return (($this->_row['allow_splash_only_nodes'] == 't') ? true : false);
920    }
921
922    /**
923     * Set if nodes are allowed to be set as splash-only (no login)
924     *
925     * @param bool $value The new value, true or false
926     *
927     * @return bool True on success, false on failure
928     *
929     * @access public
930     */
931    public function setSplashOnlyNodesAllowed($value)
932    {
933        // Init values
934        $retval = true;
935
936        if ($value != $this->getSplashOnlyNodesAllowed()) {
937            $db = AbstractDb::getObject();
938            $value ? $value = 'TRUE' : $value = 'FALSE';
939            $retval = $db->execSqlUpdate("UPDATE networks SET allow_splash_only_nodes = {$value} WHERE network_id = '{$this->getId()}'", false);
940            $this->refresh();
941        }
942
943        return $retval;
944    }
945
946    /**
947     * Get a GisPoint object
948     *
949     * @return object GisPoint object
950     */
951    public function getGisLocation()
952    {
953        return new GisPoint($this->_row['gmaps_initial_latitude'], $this->_row['gmaps_initial_longitude'], $this->_row['gmaps_initial_zoom_level']);
954    }
955
956    /**
957     * Set the network's GisPoint object
958     *
959     * @param $value The new GisPoint object
960     *
961     * @return bool True on success, false on failure
962     */
963    public function setGisLocation($pt)
964    {
965            $retval=false;
966        $db = AbstractDb::getObject();
967
968        if (!empty ($pt)) {
969            $lat = $db->escapeString($pt->getLatitude());
970            $long = $db->escapeString($pt->getLongitude());
971            $alt = $db->escapeString($pt->getAltitude());
972
973            if (!empty ($lat) && !empty ($long) && !empty ($alt)) {
974                $db->execSqlUpdate("UPDATE networks SET gmaps_initial_latitude = $lat, gmaps_initial_longitude = $long, gmaps_initial_zoom_level = $alt WHERE network_id = '{$this->getId()}'");
975            $retval=true;
976            }
977            else {
978                $db->execSqlUpdate("UPDATE networks SET gmaps_initial_latitude = NULL, gmaps_initial_longitude = NULL, gmaps_initial_zoom_level = NULL WHERE network_id = '{$this->getId()}'");
979            }
980            $this->refresh();
981        }
982        return $retval;
983    }
984
985    /**
986     * Retreives the default Google maps type
987     *
988     * @return string Default Google maps type
989     */
990    public function getGisMapType()
991    {
992        return $this->_row['gmaps_map_type'];
993    }
994
995    /**
996     * Set the network's default Google maps type
997     *
998     * @param $value The new default Google maps type
999     *
1000     * @return bool True on success, false on failure
1001     */
1002    public function setGisMapType($value)
1003    {
1004
1005        $db = AbstractDb::getObject();
1006
1007        // Init values
1008        $retval = true;
1009
1010        if ($value != $this->getGisMapType()) {
1011            $value = $db->escapeString($value);
1012            $retval = $db->execSqlUpdate("UPDATE networks SET gmaps_map_type = '{$value}' WHERE network_id = '{$this->getId()}'", false);
1013            $this->refresh();
1014        }
1015        return $retval;
1016    }
1017
1018    /**
1019     * Get an interface to pick a Google maps type
1020     *
1021     * @param string $user_prefix           A identifier provided by the
1022     *                                      programmer to recognise it's
1023     *                                      generated html form
1024     * @param string $pre_selected_map_type The Google map type to be
1025     *                                      pre-selected in the form object
1026     *
1027     * @return string HTML markup
1028
1029     */
1030    public static function getSelectGisMapType($user_prefix, $pre_selected_map_type = "G_NORMAL_MAP")
1031    {
1032
1033        $db = AbstractDb::getObject();
1034
1035        // Init values
1036        $_map_types = array (array ("G_NORMAL_MAP", _("Map")), array ("G_SATELLITE_MAP", _("Satellite")), array ("G_HYBRID_MAP", _("Hybrid")));
1037
1038        $_name = $user_prefix;
1039
1040        if ($pre_selected_map_type) {
1041            $_selectedID = $pre_selected_map_type;
1042        }
1043        else {
1044            $_selectedID = null;
1045        }
1046
1047        $_html = FormSelectGenerator :: generateFromArray($_map_types, $_selectedID, $_name, null, false);
1048
1049        return $_html;
1050    }
1051
1052    /**
1053     * Get's the splash-only user.
1054     *
1055     * This is the user that people logged-in at a splash-only hotspot will
1056     * show up as.  This user always has multiple-login capabilities.
1057     *
1058     * @param string $username The username of the user
1059     * @param string $account_origin The account origin
1060     *
1061     * @return object A User object
1062     *
1063     * @access public
1064     */
1065    public function getSplashOnlyUser()
1066    {
1067        $username = 'SPLASH_ONLY_USER';
1068
1069        $user = User :: getUserByUsernameAndOrigin($username, $this);
1070        if (!$user) {
1071            $user = User :: createUser(get_guid(), $username, $this, '', '');
1072            $user->setAccountStatus(ACCOUNT_STATUS_ALLOWED);
1073        }
1074        return $user;
1075    }
1076
1077    /**
1078     * Find out the total number of users in this networks's database
1079     *
1080     * @return int Number of users
1081     */
1082    public function getNumUsers()
1083    {
1084
1085        $db = AbstractDb::getObject();
1086
1087        // Init values
1088        $_retval = 0;
1089        $_row = null;
1090        $_useCache = false;
1091        $_cachedData = null;
1092
1093        // Create new cache objects (valid for 1 minute)
1094        $_cache = new Cache('network_'.$this->_id.'_num_users', $this->_id, 60);
1095
1096        // Check if caching has been enabled.
1097        if ($_cache->isCachingEnabled) {
1098            $_cachedData = $_cache->getCachedData();
1099
1100            if ($_cachedData) {
1101                // Return cached data.
1102                $_useCache = true;
1103                $_retval = $_cachedData;
1104            }
1105        }
1106
1107        if (!$_useCache) {
1108            // Get number of users
1109            $_network_id = $db->escapeString($this->_id);
1110            $db->execSqlUniqueRes("SELECT COUNT(user_id) FROM users WHERE account_origin='$_network_id'", $_row, false);
1111
1112            // String has been found
1113            $_retval = $_row['count'];
1114
1115            // Check if caching has been enabled.
1116            if ($_cache->isCachingEnabled) {
1117                // Save data into cache, because it wasn't saved into cache before.
1118                $_cache->saveCachedData($_retval);
1119            }
1120        }
1121
1122        return $_retval;
1123    }
1124
1125    /**
1126     * Find out how many users are valid in this networks's database
1127     *
1128     * @return int Number of valid users
1129     */
1130    public function getNumValidUsers()
1131    {
1132
1133        $db = AbstractDb::getObject();
1134
1135        // Init values
1136        $_retval = 0;
1137        $_row = null;
1138        $_useCache = false;
1139        $_cachedData = null;
1140
1141        // Create new cache objects (valid for 1 minute)
1142        $_cache = new Cache('network_'.$this->_id.'_num_valid_users', $this->_id, 60);
1143
1144        // Check if caching has been enabled.
1145        if ($_cache->isCachingEnabled) {
1146            $_cachedData = $_cache->getCachedData();
1147
1148            if ($_cachedData) {
1149                // Return cached data.
1150                $_useCache = true;
1151                $_retval = $_cachedData;
1152            }
1153        }
1154
1155        if (!$_useCache) {
1156            // Get number of valid users
1157            $_network_id = $db->escapeString($this->_id);
1158            $db->execSqlUniqueRes("SELECT COUNT(user_id) FROM users WHERE account_status = ".ACCOUNT_STATUS_ALLOWED." AND account_origin='$_network_id'", $_row, false);
1159            // String has been found
1160            $_retval = $_row['count'];
1161
1162            // Check if caching has been enabled.
1163            if ($_cache->isCachingEnabled) {
1164                // Save data into cache, because it wasn't saved into cache before.
1165                $_cache->saveCachedData($_retval);
1166            }
1167        }
1168
1169        return $_retval;
1170    }
1171
1172    /**
1173     * Find out how many users are online on the entire network or at a
1174     * specific Hotspot on the network
1175     *
1176     * @return int Number of online users
1177     */
1178    public function getNumOnlineUsers()
1179    {
1180
1181        $db = AbstractDb::getObject();
1182
1183        // Init values
1184        $_retval = 0;
1185        $_row = null;
1186        $_useCache = false;
1187        $_cachedData = null;
1188
1189        // Create new cache objects (valid for 1 minute)
1190        $_cache = new Cache('network_'.$this->_id.'_num_online_users', $this->_id, 60);
1191
1192        // Check if caching has been enabled.
1193        if ($_cache->isCachingEnabled) {
1194            $_cachedData = $_cache->getCachedData();
1195
1196            if ($_cachedData) {
1197                // Return cached data.
1198                $_useCache = true;
1199                $_retval = $_cachedData;
1200            }
1201        }
1202
1203        if (!$_useCache) {
1204            // Get number of online users
1205            $_network_id = $db->escapeString($this->_id);
1206            $db->execSqlUniqueRes("SELECT COUNT(conn_id) FROM connections NATURAL JOIN nodes JOIN networks ON (nodes.network_id=networks.network_id AND networks.network_id='$_network_id') "."WHERE connections.token_status='".TOKEN_INUSE."' ", $_row, false);
1207
1208            // String has been found
1209            $_retval = $_row['count'];
1210
1211            // Check if caching has been enabled.
1212            if ($_cache->isCachingEnabled) {
1213                // Save data into cache, because it wasn't saved into cache before.
1214                $_cache->saveCachedData($_retval);
1215            }
1216        }
1217
1218        return $_retval;
1219    }
1220
1221    /**
1222     * Find out how many nodes are registered in this networks's database
1223     *
1224     * @return int Number of nodes
1225     */
1226    public function getNumNodes()
1227    {
1228
1229        $db = AbstractDb::getObject();
1230
1231        // Init values
1232        $_retval = 0;
1233        $_row = null;
1234        $_useCache = false;
1235        $_cachedData = null;
1236
1237        // Create new cache objects (valid for 5 minutes)
1238        $_cache = new Cache('network_'.$this->_id.'_num_nodes', $this->_id, 300);
1239
1240        // Check if caching has been enabled.
1241        if ($_cache->isCachingEnabled) {
1242            $_cachedData = $_cache->getCachedData();
1243
1244            if ($_cachedData) {
1245                // Return cached data.
1246                $_useCache = true;
1247                $_retval = $_cachedData;
1248            }
1249        }
1250
1251        if (!$_useCache) {
1252            // Get number of nodes
1253            $_network_id = $db->escapeString($this->_id);
1254            $db->execSqlUniqueRes("SELECT COUNT(node_id) FROM nodes WHERE network_id = '$_network_id'", $_row, false);
1255
1256            // String has been found
1257            $_retval = $_row['count'];
1258
1259            // Check if caching has been enabled.
1260            if ($_cache->isCachingEnabled) {
1261                // Save data into cache, because it wasn't saved into cache before.
1262                $_cache->saveCachedData($_retval);
1263            }
1264        }
1265
1266        return $_retval;
1267    }
1268
1269    /**
1270     * Find out how many nodes are deployed in this networks's database
1271     *
1272     * @return int Number of deployed nodes
1273     */
1274    public function getNumDeployedNodes()
1275    {
1276
1277        $db = AbstractDb::getObject();
1278
1279        // Init values
1280        $_retval = 0;
1281        $_row = null;
1282        $_useCache = false;
1283        $_cachedData = null;
1284
1285        // Create new cache objects (valid for 5 minutes)
1286        $_cache = new Cache('network_'.$this->_id.'_num_deployed_nodes', $this->_id, 300);
1287
1288        // Check if caching has been enabled.
1289        if ($_cache->isCachingEnabled) {
1290            $_cachedData = $_cache->getCachedData();
1291
1292            if ($_cachedData) {
1293                // Return cached data.
1294                $_useCache = true;
1295                $_retval = $_cachedData;
1296            }
1297        }
1298
1299        if (!$_useCache) {
1300            // Get number of deployed nodes
1301            $_network_id = $db->escapeString($this->_id);
1302            $db->execSqlUniqueRes("SELECT COUNT(node_id) FROM nodes WHERE network_id = '$_network_id' AND (node_deployment_status = 'DEPLOYED' OR node_deployment_status = 'NON_WIFIDOG_NODE')", $_row, false);
1303
1304            // String has been found
1305            $_retval = $_row['count'];
1306
1307            // Check if caching has been enabled.
1308            if ($_cache->isCachingEnabled) {
1309                // Save data into cache, because it wasn't saved into cache before.
1310                $_cache->saveCachedData($_retval);
1311            }
1312        }
1313
1314        return $_retval;
1315    }
1316
1317    /**
1318     * Find out how many deployed nodes are online in this networks's database
1319     *
1320     * @param bool $nonMonitoredOnly Return number of non-monitored nodes only
1321     *
1322     * @return int Number of deployed nodes which are online
1323     */
1324    public function getNumOnlineNodes($nonMonitoredOnly = false)
1325    {
1326
1327        $db = AbstractDb::getObject();
1328
1329        // Init values
1330        $_retval = 0;
1331        $_row = null;
1332        $_useCache = false;
1333        $_cachedData = null;
1334
1335        // Create new cache objects (valid for 5 minutes)
1336        if ($nonMonitoredOnly) {
1337            $_cache = new Cache('network_'.$this->_id.'_num_online_nodes_non_monitored', $this->_id, 300);
1338        } else {
1339            $_cache = new Cache('network_'.$this->_id.'_num_online_nodes', $this->_id, 300);
1340        }
1341
1342        // Check if caching has been enabled.
1343        if ($_cache->isCachingEnabled) {
1344            $_cachedData = $_cache->getCachedData();
1345
1346            if ($_cachedData) {
1347                // Return cached data.
1348                $_useCache = true;
1349                $_retval = $_cachedData;
1350            }
1351        }
1352
1353        if (!$_useCache) {
1354            // Get number of online nodes
1355            $_network_id = $db->escapeString($this->_id);
1356
1357            if ($nonMonitoredOnly) {
1358                $db->execSqlUniqueRes("SELECT COUNT(node_id) FROM nodes WHERE network_id = '$_network_id' AND node_deployment_status = 'NON_WIFIDOG_NODE' AND ((CURRENT_TIMESTAMP-last_heartbeat_timestamp) >= interval '5 minutes')", $_row, false);
1359            } else {
1360                $db->execSqlUniqueRes("SELECT COUNT(node_id) FROM nodes WHERE network_id = '$_network_id' AND (node_deployment_status = 'DEPLOYED' OR node_deployment_status = 'NON_WIFIDOG_NODE') AND ((CURRENT_TIMESTAMP-last_heartbeat_timestamp) < interval '5 minutes')", $_row, false);
1361            }
1362
1363            // String has been found
1364            $_retval = $_row['count'];
1365
1366            // Check if caching has been enabled.
1367            if ($_cache->isCachingEnabled) {
1368                // Save data into cache, because it wasn't saved into cache before.
1369                $_cache->saveCachedData($_retval);
1370            }
1371        }
1372
1373        return $_retval;
1374    }
1375
1376    /**
1377     * Are nodes allowed to redirect users to an arbitrary web page instead of
1378     * the portal?
1379     *
1380     * @return bool True or false
1381     *
1382     * @access public
1383     */
1384    public function getCustomPortalRedirectAllowed()
1385    {
1386        return (($this->_row['allow_custom_portal_redirect'] == 't') ? true : false);
1387    }
1388
1389    /**
1390     * Set if nodes are allowed to redirect users to an arbitrary web page
1391     * instead of the portal?
1392     *
1393     * @param bool $value The new value, true or false
1394     *
1395     * @return bool True on success, false on failure
1396     *
1397     * @access public
1398     */
1399    public function setCustomPortalRedirectAllowed($value)
1400    {
1401        // Init values
1402        $retval = true;
1403
1404        if ($value != $this->getCustomPortalRedirectAllowed()) {
1405            $db = AbstractDb::getObject();
1406            $value ? $value = 'TRUE' : $value = 'FALSE';
1407            $retval = $db->execSqlUpdate("UPDATE networks SET allow_custom_portal_redirect = {$value} WHERE network_id = '{$this->getId()}'", false);
1408            $this->refresh();
1409        }
1410
1411        return $retval;
1412    }
1413
1414    /**
1415     * Does the user have admin access to this network?
1416     *
1417     * @return bool true our false
1418     *
1419     * @access public
1420     */
1421    public function DEPRECATEDhasAdminAccess(User $user)
1422    {
1423
1424        $db = AbstractDb::getObject();
1425
1426        // Init values
1427        $row = null;
1428        $retval = false;
1429
1430        if ($user != null) {
1431                if ($user->DEPRECATEDisSuperAdmin()) {
1432                    $retval = true;
1433                }
1434        }
1435
1436        return $retval;
1437    }
1438
1439    /**
1440     * Get an array of all Content linked to the network
1441     *
1442     * @param bool   $exclude_subscribed_content Exclude subscribed content?
1443     * @param object $subscriber                 The User object used to
1444     *                                           discriminate the content
1445     *
1446     * @return array An array of Content or an empty array
1447     */
1448    /*public function getAllContent($exclude_subscribed_content = false, $subscriber = null)
1449     {
1450
1451        $db = AbstractDb::getObject();
1452
1453        // Init values
1454        $content_rows = null;
1455        $retval = array ();
1456
1457        // Get all network, but exclude user subscribed content if asked
1458        if ($exclude_subscribed_content == true && $subscriber) {
1459        $sql = "SELECT content_id FROM network_has_content WHERE network_id='$this->_id' AND content_id NOT IN (SELECT content_id FROM user_has_content WHERE user_id = '{$subscriber->getId()}') ORDER BY subscribe_timestamp DESC";
1460        } else {
1461        $sql = "SELECT content_id FROM network_has_content WHERE network_id='$this->_id' ORDER BY subscribe_timestamp DESC";
1462        }
1463
1464        $db->execSql($sql, $content_rows, false);
1465
1466        if ($content_rows != null) {
1467        foreach ($content_rows as $content_row) {
1468        $retval[] = Content :: getObject($content_row['content_id']);
1469        }
1470        }
1471
1472        return $retval;
1473        }
1474        */
1475
1476    /**
1477     * Retreives the admin interface of this object
1478     *
1479     * @return string The HTML fragment for this interface
1480     */
1481    public function getAdminUI()
1482    {
1483        require_once('classes/InterfaceElements.php');
1484        // Init values
1485        $html = '';
1486
1487        /*
1488         * Begin with admin interface
1489         */
1490        $html .= "<fieldset class='admin_container ".get_class($this)."'>\n";
1491        $html .= "<legend>"._("Network management")."</legend>\n";
1492        $html .= "<ul class='admin_element_list'>\n";
1493
1494        /*
1495         * Content management
1496         */
1497        $title = _("Network content");
1498        $name = "network_".$this->_id."_content";
1499        $data = Content::getLinkedContentUI($name, "network_has_content", "network_id", $this->_id, $display_page = "portal");
1500        $html .= InterfaceElements::generateAdminSectionContainer("network_content", $title, $data);
1501
1502        /*
1503         * Network information
1504         */
1505        $html_network_information = array();
1506
1507        // network_id
1508        $title = _("Network ID");
1509        $data = htmlspecialchars($this->getId(), ENT_QUOTES);
1510        $html_network_information[] = InterfaceElements::generateAdminSectionContainer("network_id", $title, $data);
1511
1512        // name
1513        $title = _("Network name");
1514        $data = InterfaceElements::generateInputText("network_" . $this->getId() . "_name", $this->getName(), "network_name_input");
1515        $html_network_information[] = InterfaceElements::generateAdminSectionContainer("network_name", $title, $data);
1516
1517        // creation_date
1518        $title = _("Network creation date");
1519        $data = DateTimeWD::getSelectDateTimeUI(new DateTimeWD($this->getCreationDate()), "network_" . $this->getId() . "_creation_date", DateTimeWD::INTERFACE_DATETIME_FIELD, "network_creation_date_input");
1520        $html_network_information[] = InterfaceElements::generateAdminSectionContainer("network_creation_date", $title, $data);
1521
1522        // homepage_url
1523        $title = _("Network's web site");
1524        $data = InterfaceElements::generateInputText("network_" . $this->getId() . "_homepage_url", $this->getWebSiteURL(), "network_homepage_url_input");
1525        $html_network_information[] = InterfaceElements::generateAdminSectionContainer("network_homepage_url", $title, $data);
1526
1527        // tech_support_email
1528        $title = _("Technical support email");
1529        $data = InterfaceElements::generateInputText("network_" . $this->getId() . "_tech_support_email", $this->getTechSupportEmail(), "network_tech_support_email_input");
1530        $html_network_information[] = InterfaceElements::generateAdminSectionContainer("network_tech_support_email", $title, $data);
1531
1532        // Build section
1533        $html .= InterfaceElements::generateAdminSectionContainer("network_information", _("Information about the network"), implode(null, $html_network_information));
1534
1535        /*
1536         * Network authentication
1537         */
1538        $html_network_authentication = array();
1539
1540        //  network_authenticator_class
1541        $title = _("Network authenticator class");
1542        $help = _("The subclass of Authenticator to be used for user authentication. Example: AuthenticatorRadius");
1543        $name = "network_" . $this->getId() . "_network_authenticator_class";
1544        $value = htmlspecialchars($this->getAuthenticatorClassName(), ENT_QUOTES);
1545        $data = $this->getSelectAuthenticator($name, $value);
1546        $html_network_authentication[] = InterfaceElements::generateAdminSectionContainer("network_network_authenticator_class", $title, $data, $help);
1547
1548        //  network_authenticator_params
1549        $title = _("Authenticator parameters");
1550        $help = _("The explicit parameters to be passed to the authenticator. You MUST read the constructor documentation of your desired authenticator class (in wifidog/classes/Authenticators/) BEFORE you start playing with this.  Example: 'my_network_id', '192.168.0.11', 1812, 1813, 'secret_key', 'CHAP_MD5'");
1551        $data = InterfaceElements::generateInputText("network_" . $this->getId() . "_network_authenticator_params", $this->getAuthenticatorConstructorParams(), "network_network_authenticator_params_input");
1552        $html_network_authentication[] = InterfaceElements::generateAdminSectionContainer("network_network_authenticator_params", $title, $data, $help);
1553
1554        // Build section
1555        $html .= InterfaceElements::generateAdminSectionContainer("network_authentication", _("Network Authentication"), implode(null, $html_network_authentication));
1556
1557        /*
1558         * Network properties
1559         */
1560        $html_network_properties = array();
1561
1562        //  is_default_network
1563        $title = _("Is this network the default network?");
1564        $data = InterfaceElements::generateInputCheckbox("network_" . $this->getId() . "_is_default_network", "", _("Yes"), $this->isDefaultNetwork(), "network_is_default_network_radio");
1565        $html_network_properties[] = InterfaceElements::generateAdminSectionContainer("network_is_default_network", $title, $data);
1566
1567        //  theme_pack
1568        $title = _("Selected theme pack for this network");
1569        $data = ThemePack::getSelectUI("network_" . $this->getId() . "_theme_pack", $this->getThemePack());
1570        $html_network_properties[] = InterfaceElements::generateAdminSectionContainer("network_theme_pack", $title, $data);
1571
1572        // Build section
1573        $html .= InterfaceElements::generateAdminSectionContainer("network_properties", _("Network properties"), implode(null, $html_network_properties));
1574
1575        /*
1576         * Network's node properties
1577         */
1578        $html_network_node_properties = array();
1579
1580        //  allow_splash_only_nodes
1581        $title = _("Splash-only nodes");
1582        $help = _("Are nodes allowed to be set as splash-only (no login)?");
1583        $data = InterfaceElements::generateInputCheckbox("network_" . $this->getId() . "_allow_splash_only_nodes", "", _("Yes"), $this->getSplashOnlyNodesAllowed(), "network_allow_splash_only_nodes_radio");
1584        $html_network_node_properties[] = InterfaceElements::generateAdminSectionContainer("network_allow_splash_only_nodes", $title, $data, $help);
1585
1586        //  allow_custom_portal_redirect
1587        $title = _("Portal page redirection");
1588        $help = _("Are nodes allowed to redirect users to an arbitrary web page instead of the portal?");
1589        $data = InterfaceElements::generateInputCheckbox("network_" . $this->getId() . "_allow_custom_portal_redirect", "", _("Yes"), $this->getCustomPortalRedirectAllowed(), "network_allow_custom_portal_redirect_radio");
1590        $html_network_node_properties[] = InterfaceElements::generateAdminSectionContainer("network_allow_custom_portal_redirect", $title, $data, $help);
1591
1592        // Build section
1593        $html .= InterfaceElements::generateAdminSectionContainer("network_node_properties", _("Network's node properties"), implode(null, $html_network_node_properties));
1594
1595        /*
1596         * Network's user verification
1597         */
1598        $html_network_user_verification = array();
1599
1600        //  validation_grace_time
1601        $title = _("Validation grace period");
1602        $help = _("The length of the validation grace period in seconds.  A new user is granted Internet access for this period check his email and validate his account.");
1603        $data = InterfaceElements::generateInputText("network_" . $this->getId() . "_validation_grace_time", $this->getValidationGraceTime(), "network_validation_grace_time_input");
1604        $html_network_user_verification[] = InterfaceElements::generateAdminSectionContainer("network_validation_grace_time", $title, $data, $help);
1605
1606        //  validation_email_from_address
1607        $title = _("This will be the from address of the validation email");
1608        $data = InterfaceElements::generateInputText("network_" . $this->getId() . "_validation_email_from_address", $this->getValidationEmailFromAddress(), "network_validation_email_from_address_input");
1609        $html_network_user_verification[] = InterfaceElements::generateAdminSectionContainer("network_validation_email_from_address", $title, $data);
1610
1611        //  allow_multiple_login
1612        $title = _("Multiple connections");
1613        $help = _("Can an account be connected more than once at the same time?");
1614        $data = InterfaceElements::generateInputCheckbox("network_" . $this->getId() . "_allow_multiple_login", "", _("Yes"), $this->getMultipleLoginAllowed(), "network_allow_multiple_login_radio");
1615        $html_network_user_verification[] = InterfaceElements::generateAdminSectionContainer("network_allow_multiple_login", $title, $data, $help);
1616
1617        // Build section
1618        $html .= InterfaceElements::generateAdminSectionContainer("network_user_verification", _("Network's user verification"), implode(null, $html_network_user_verification));
1619
1620        /*
1621         * Access management
1622         */
1623        $html_access_rights = array();
1624
1625        /*
1626         * Access rights
1627         */
1628        if (true) {
1629            require_once('classes/Stakeholder.php');
1630            $html_access_rights = Stakeholder::getAssignStakeholdersUI($this);
1631            $html .= InterfaceElements::generateAdminSectionContainer("access_rights", _("Access rights"), $html_access_rights);
1632        }
1633        /*
1634         * Network GIS data
1635         */
1636        if (defined('GMAPS_HOTSPOTS_MAP_ENABLED') && GMAPS_HOTSPOTS_MAP_ENABLED == true) {
1637            $html_network_gis_data = array();
1638
1639            $gis_point = $this->getGisLocation();
1640            $gis_lat_name = "network_" . $this->getId() . "_gis_latitude";
1641            $gis_lat_value = htmlspecialchars($gis_point->getLatitude(), ENT_QUOTES);
1642            $gis_long_name = "network_" . $this->getId() . "_gis_longitude";
1643            $gis_long_value = htmlspecialchars($gis_point->getLongitude(), ENT_QUOTES);
1644            $gis_alt_name = "network_" . $this->getId() . "_gis_altitude";
1645            $gis_alt_value = htmlspecialchars($gis_point->getAltitude(), ENT_QUOTES);
1646
1647            $html_network_gis_data[] = '<p>'._("Note that to be valid, all 3 values must be present.")."</p>\n";
1648            $title = _("Latitude");
1649            $help = _("Center latitude for the area covered by your wireless network");
1650            $data = InterfaceElements::generateInputText($gis_lat_name, $gis_lat_value, "network_gis_latitude_input");
1651            $html_network_gis_data[] = InterfaceElements::generateAdminSectionContainer("network_gis_latitude", $title, $data, $help);
1652
1653            $title = _("Longitude");
1654            $help = _("Center longitude for the area covered by your wireless network");
1655            $data = InterfaceElements::generateInputText($gis_long_name, $gis_long_value, "network_gis_longitude_input");
1656            $html_network_gis_data[] = InterfaceElements::generateAdminSectionContainer("network_gis_longitude", $title, $data, $help);
1657
1658            $title = _("Zoomlevel");
1659            $help = _("Zoomlevel of the Google Map.  12 is a typical value.");
1660            $data = InterfaceElements::generateInputText($gis_alt_name, $gis_alt_value, "network_gis_altitude_input");
1661            $html_network_gis_data[] = InterfaceElements::generateAdminSectionContainer("network_gis_altitude", $title, $data, $help);
1662
1663            $title = _("Map type");
1664            $help = _("Default Google Map type for your the area of your wireless network");
1665            $data = $this->getSelectGisMapType("network_" . $this->getId() . "_gmaps_map_type", $this->getGisMapType());
1666            $html_network_gis_data[] = InterfaceElements::generateAdminSectionContainer("network_gmaps_map_type", $title, $data, $help);
1667
1668            // Build section
1669            $html .= InterfaceElements::generateAdminSectionContainer("network_gis_data", _("GIS data"), implode(null, $html_network_gis_data));
1670        }
1671       
1672        // Profile templates
1673        $title = _("Network profile templates");
1674        $name = "network_".$this->_id."_profile_templates";
1675        $data = ProfileTemplate::getLinkedProfileTemplateUI($name, "network_has_profile_templates", "network_id", $this->_id);
1676        $html .= InterfaceElements::generateAdminSectionContainer("network_profile_templates", $title, $data);
1677
1678        $html .= "</ul>\n";
1679        $html .= "</fieldset>";
1680
1681        return $html;
1682    }
1683
1684    /**
1685     * Process admin interface of this object.
1686     *
1687     * @return void
1688     *
1689     * @access public
1690     */
1691    public function processAdminUI()
1692    {
1693        $user = User::getCurrentUser();
1694
1695        if (!$this->DEPRECATEDhasAdminAccess($user)) {
1696            throw new Exception(_('Access denied!'));
1697        }
1698
1699        // Content management
1700        $name = "network_".$this->_id."_content";
1701        Content :: processLinkedContentUI($name, 'network_has_content', 'network_id', $this->_id);
1702
1703        // name
1704        $name = "network_".$this->getId()."_name";
1705        $this->setName($_REQUEST[$name]);
1706
1707        // creation_date
1708        $name = "network_".$this->getId()."_creation_date";
1709        $this->setCreationDate($_REQUEST[$name]);
1710
1711        // homepage_url
1712        $name = "network_".$this->getId()."_homepage_url";
1713        $this->setWebSiteUrl($_REQUEST[$name]);
1714
1715        // tech_support_email
1716        $name = "network_".$this->getId()."_tech_support_email";
1717        $this->setTechSupportEmail($_REQUEST[$name]);
1718
1719        //  network_authenticator_class
1720        $name = "network_".$this->getId()."_network_authenticator_class";
1721        $this->setAuthenticatorClassName($_REQUEST[$name]);
1722
1723        //  network_authenticator_params
1724        $name = "network_".$this->getId()."_network_authenticator_params";
1725        $this->setAuthenticatorConstructorParams($_REQUEST[$name]);
1726
1727        //  is_default_network
1728        $name = "network_".$this->getId()."_is_default_network";
1729        if (!empty ($_REQUEST[$name]) && $_REQUEST[$name] == 'on')
1730        $this->setAsDefaultNetwork();
1731
1732        //  validation_grace_time
1733        $name = "network_".$this->getId()."_validation_grace_time";
1734        $this->setValidationGraceTime($_REQUEST[$name]);
1735
1736        //  validation_email_from_address
1737        $name = "network_".$this->getId()."_validation_email_from_address";
1738        $this->setValidationEmailFromAddress($_REQUEST[$name]);
1739
1740        //  theme_pack
1741        $name = "network_".$this->getId()."_theme_pack";
1742        if (!empty ($_REQUEST[$name])) {
1743            $theme_pack = ThemePack::getObject($_REQUEST[$name]);
1744        }
1745        else {
1746            $theme_pack = null;
1747        }
1748        $this->setThemePack($theme_pack);
1749
1750        //  allow_multiple_login
1751        $name = "network_".$this->getId()."_allow_multiple_login";
1752        $this->setMultipleLoginAllowed(empty ($_REQUEST[$name]) ? false : true);
1753
1754        //  allow_splash_only_nodes
1755        $name = "network_".$this->getId()."_allow_splash_only_nodes";
1756        $this->setSplashOnlyNodesAllowed(empty ($_REQUEST[$name]) ? false : true);
1757
1758        //  allow_custom_portal_redirect
1759        $name = "network_".$this->getId()."_allow_custom_portal_redirect";
1760        $this->setCustomPortalRedirectAllowed(empty ($_REQUEST[$name]) ? false : true);
1761       
1762        // Access rights
1763            require_once('classes/Stakeholder.php');
1764        Stakeholder::processAssignStakeholdersUI($this, $errMsg);
1765        if(!empty($errMsg)) {
1766        echo $errMsg;
1767        }
1768       
1769        // GIS data
1770        if (defined('GMAPS_HOTSPOTS_MAP_ENABLED') && GMAPS_HOTSPOTS_MAP_ENABLED == true) {
1771            $gis_lat_name = "network_".$this->getId()."_gis_latitude";
1772            $gis_long_name = "network_".$this->getId()."_gis_longitude";
1773            $gis_alt_name = "network_".$this->getId()."_gis_altitude";
1774            $this->setGisLocation(new GisPoint($_REQUEST[$gis_lat_name], $_REQUEST[$gis_long_name], $_REQUEST[$gis_alt_name]));
1775
1776            $name = "network_".$this->getId()."_gmaps_map_type";
1777            $this->setGisMapType($_REQUEST[$name]);
1778        }
1779       
1780        // Profile templates
1781        $name = "network_".$this->_id."_profile_templates";
1782        ProfileTemplate :: processLinkedProfileTemplateUI($name, 'network_has_profile_templates', 'network_id', $this->_id);
1783
1784        // Node creation
1785        $new_node = Node :: processCreateNewObjectUI();
1786        if ($new_node) {
1787            $url = GENERIC_OBJECT_ADMIN_ABS_HREF."?".http_build_query(array ("object_class" => "Node", "action" => "edit", "object_id" => $new_node->getId()));
1788            header("Location: {$url}");
1789        }
1790    }
1791
1792    /**
1793     * Add network-wide content to this network
1794     *
1795     * @param object Content object
1796     *
1797     * @return void
1798     *
1799     * @access public
1800     */
1801    public function addContent(Content $content)
1802    {
1803        $db = AbstractDb::getObject();
1804
1805        $content_id = $db->escapeString($content->getId());
1806        $sql = "INSERT INTO network_has_content (network_id, content_id) VALUES ('$this->_id','$content_id')";
1807        $db->execSqlUpdate($sql, false);
1808    }
1809
1810    /**
1811     * Remove network-wide content from this network
1812     *
1813     * @param object Content object
1814     *
1815     * @return void
1816     *
1817     * @access public
1818     */
1819    public function removeContent(Content $content)
1820    {
1821        $db = AbstractDb::getObject();
1822
1823        $content_id = $db->escapeString($content->getId());
1824        $sql = "DELETE FROM network_has_content WHERE network_id='$this->_id' AND content_id='$content_id'";
1825        $db->execSqlUpdate($sql, false);
1826    }
1827
1828
1829    /**
1830     * Add a profile template to this network
1831     *
1832     * @param object ProfileTemplate object
1833     *
1834     * @return void
1835     *
1836     * @access public
1837     */
1838    public function addProfileTemplate(ProfileTemplate $profile_template)
1839    {
1840        $db = AbstractDb::getObject();
1841
1842        $profile_template_id = $db->escapeString($profile_template->getId());
1843        $sql = "INSERT INTO network_has_profile_templates (network_id, profile_template_id) VALUES ('$this->_id','$profile_template_id')";
1844        $db->execSqlUpdate($sql, false);
1845    }
1846
1847    /**
1848     * Remove a profile template to this network
1849     *
1850     * @param object ProfileTemplate object
1851     *
1852     * @return void
1853     *
1854     * @access public
1855     */
1856    public function removeProfileTemplate(ProfileTemplate $profile_template)
1857    {
1858        $db = AbstractDb::getObject();
1859
1860        $profile_template_id = $db->escapeString($profile_template->getId());
1861        $sql = "DELETE FROM network_has_profile_templates WHERE network_id='$this->_id' AND profile_template_id='$profile_template_id'";
1862        $db->execSqlUpdate($sql, false);
1863    }
1864
1865    /**Get an array of all ProfileTemplates linked to this network
1866     * @return an array of ProfileTemplates or an empty arrray */
1867    function getAllProfileTemplates() {
1868        $db = AbstractDb::getObject();
1869        $retval = array ();
1870        $profile_template_rows = null;
1871        $sql = "SELECT profile_template_id FROM network_has_profile_templates WHERE network_id='$this->_id'";
1872        $db->execSql($sql, $profile_template_rows, false);
1873        if ($profile_template_rows != null) {
1874            foreach ($profile_template_rows as $profile_template_row) {
1875                $retval[] = ProfileTemplate :: getObject($profile_template_row['profile_template_id']);
1876            }
1877        }
1878        return $retval;
1879    }
1880
1881    /**
1882     * Delete this Object form the it's storage mechanism
1883     *
1884     * @param string &$errmsg Returns an explanation of the error on failure
1885     *
1886     * @return bool true on success, false on failure or access denied
1887     *
1888     * @access public
1889     */
1890    public function delete(& $errmsg)
1891    {
1892        // Init values
1893        $retval = false;
1894
1895        $user = User :: getCurrentUser();
1896        if (!$user->DEPRECATEDisSuperAdmin()) {
1897            $errmsg = _('Access denied (must have super admin access)');
1898        } else {
1899            if ($this->isDefaultNetwork() === true) {
1900                $errmsg = _('Cannot delete default network, create another one and select it before remove this one.');
1901            } else {
1902                $db = AbstractDb::getObject();
1903                $id = $db->escapeString($this->getId());
1904                if (!$db->execSqlUpdate("DELETE FROM networks WHERE network_id='{$id}'", false)) {
1905                    $errmsg = _('Could not delete network!');
1906                } else {
1907                    $retval = true;
1908                }
1909            }
1910        }
1911
1912        return $retval;
1913    }
1914    /**
1915     * Reloads the object from the database.
1916     *
1917     * Should normally be called after a set operation
1918     *
1919     * @return void
1920     *
1921     * @access protected
1922     */
1923    protected function refresh()
1924    {
1925        $this->__construct($this->_id);
1926    }
1927   
1928    /** Menu hook function */
1929    static public function hookMenu() {
1930        $items = array();
1931        if($networks = Security::getObjectsWithPermission(Permission::P('NETWORK_PERM_EDIT_NETWORK_CONFIG')))
1932        {
1933                    foreach ($networks as $networkId => $network) {
1934                $items[] = array('path' => 'network/network_'.$networkId.'edit',
1935                'title' => sprintf(_("Edit %s"), $network->getName()),
1936                'url' => BASE_URL_PATH.htmlspecialchars("admin/generic_object_admin.php?object_class=Network&action=edit&object_id=$networkId")
1937                );
1938            }
1939        }
1940                $items[] = array('path' => 'network',
1941                'title' => _('Network administration'),
1942                'type' => MENU_ITEM_GROUPING);
1943           
1944            return $items; 
1945        }
1946   
1947    /**
1948     * Assigns values about network to be processed by the Smarty engine.
1949     *
1950     * @param object $smarty Smarty object
1951     * @param object $net    Network object
1952     *
1953     * @return void
1954     */
1955    public static function assignSmartyValues($smarty, $net = null)
1956    {
1957        if (!$net) {
1958            $net = Network::getCurrentNetwork();
1959        }
1960
1961        // Set network details
1962        $smarty->assign('networkName', $net ? $net->getName() : '');
1963        $smarty->assign('networkWebSiteURL', $net ? $net->getWebSiteURL() : '');
1964        // Set networks usage information
1965        $smarty->assign('networkNumOnlineUsers', $net ? $net->getNumOnlineUsers() : 0);
1966
1967        // Set networks node information
1968        $smarty->assign('networkNumDeployedNodes', $net ? $net->getNumDeployedNodes() : 0);
1969        $smarty->assign('networkNumOnlineNodes', $net ? $net->getNumOnlineNodes() : 0);
1970        $smarty->assign('networkNumNonMonitoredNodes', $net ? $net->getNumOnlineNodes(true) : 0);
1971    }
1972}
1973
1974/*
1975 * Local variables:
1976 * tab-width: 4
1977 * c-basic-offset: 4
1978 * c-hanging-comment-ender-p: nil
1979 * End:
1980 */
Note: See TracBrowser for help on using the browser.