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

Revision 1435, 82.8 KB (checked in by gbastien, 3 years ago)

Merged branch 'gbastien' for node group with the trunk:
* Added the concept of node group and hierarchy (in a not too clean way to start with, I will refactor the code before adding new functionalities to nodes and groups) (#246)
* Login and signup and logout script now receive the mac address as parameter (#675)
* Initial abuse control verification now made with the mac address (#676)

  • 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 <benoitg@coeus.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');
56require_once('classes/Security.php');
57require_once('classes/HotspotGraphElement.php');
58
59/**
60 * Abstract a Network.
61 *
62 * A network is an administrative entity with it's own users, nodes and authenticator.
63 *
64 * @package    WiFiDogAuthServer
65 * @author     Benoit Grégoire <benoitg@coeus.ca>
66 * @author     Max Horváth <max.horvath@freenet.de>
67 * @copyright  2005-2006 Benoit Grégoire, Technologies Coeus inc.
68 * @copyright  2006 Max Horváth, Horvath Web Consulting
69 */
70class Network extends GenericDataObject
71{
72    /** Object cache for the object factory (getObject())*/
73    private static $instanceArray = array();
74    protected $_hotspotGraphElement;
75
76    /**
77     * Get an instance of the object
78     *
79     * @param string $id The object id
80     *
81     * @return mixed The Content object, or null if there was an error
82     *               (an exception is also thrown)
83     *
84     * @see GenericObject
85     * @static
86     * @access public
87     */
88    public static function &getObject($id)
89    {
90        if(!isset(self::$instanceArray[$id]))
91        {
92            self::$instanceArray[$id] = new self($id);
93        }
94        return self::$instanceArray[$id];
95    }
96
97    /** Free an instanciated object
98     * @param $id The id to free
99     * Thanks and so long for all the ram.
100     */
101    public static function freeObject($id)
102    {
103        if(isset(self::$instanceArray[$id]))
104        {
105            unset(self::$instanceArray[$id]);
106        }
107    }
108
109    /**
110     * Get all the Networks configured on this server
111     *
112     * @return array An array of Network objects.  The default network is
113     *               returned first
114     *
115     * @static
116     * @access public
117     */
118    public static function getAllNetworks()
119    {
120        $retval = array ();
121        $db = AbstractDb::getObject();
122        $sql = "SELECT network_id FROM networks";
123        $network_rows = null;
124        $db->execSql($sql, $network_rows, false);
125        if ($network_rows == null) {
126            throw new Exception(_("Network::getAllNetworks:  Fatal error: No networks in the database!"));
127        }
128        foreach ($network_rows as $network_row) {
129            $retval[] = self::getObject($network_row['network_id']);
130        }
131        return $retval;
132    }
133
134    /**
135     * Get the default network
136     *
137     * @return object A Network object, NEVER returns null.
138     *
139     * @static
140     * @access public
141     */
142    public static function getDefaultNetwork()
143    {
144        $retval = null;
145        $vhost = VirtualHost :: getCurrentVirtualHost();
146        if ($vhost == null) {
147            $vhost = VirtualHost :: getDefaultVirtualHost();
148        }
149        return $vhost->getDefaultNetwork();
150    }
151
152    /**
153     * Get the current network for which the portal is displayed or to which a
154     * user is physically connected.
155     *
156     * @param bool $real_network_only NOT IMPLEMENTED YET true or false.  If
157     *                                true, the real physical network where the
158     *                                user is connected is returned, and
159     *                                the node set by setCurrentNode is ignored.
160     *
161     * @return objetc A Network object, NEVER returns null.
162     *
163     * @static
164     * @access public
165     */
166    public static function getCurrentNetwork($real_network_only = false)
167    {
168        $retval = null;
169        $current_node = Node :: getCurrentNode();
170
171        if ($current_node != null) {
172            $retval = $current_node->getNetwork();
173        } else {
174            $retval = Network :: getDefaultNetwork();
175        }
176
177        return $retval;
178    }
179
180    /**
181     * Create a new Network object in the database
182     *
183     * @param string $network_id The network id of the new network.  If absent,
184     *                           will be assigned a guid.
185     *
186     * @return mixed The newly created object, or null if there was an error
187     *
188     * @see GenericObject
189     * @static
190     * @access public
191     */
192    public static function createNewObject($network_id = null)
193    {
194        $db = AbstractDb::getObject();
195        if (empty ($network_id)) {
196            $network_id = get_guid();
197        }
198        $network_id = $db->escapeString($network_id);
199
200        $sql = "INSERT INTO networks (network_id, network_authenticator_class) VALUES ('$network_id', 'AuthenticatorLocalUser')";
201
202        if (!$db->execSqlUpdate($sql, false)) {
203            throw new Exception(_('Unable to insert the new network in the database!'));
204        }
205       
206        HotspotGraphElement::createNewObject($network_id, 'Network');
207       
208        $object = self::getObject($network_id);
209        require_once('classes/Stakeholder.php');
210        Stakeholder::add(null, Role::getObject('NETWORK_OWNER'), $object);
211        return $object;
212    }
213
214    /**
215     * Get an interface to pick an object of this class
216     *
217     * If there is only one server available, no interface is actually shown
218     *
219     * @param string $user_prefix         A identifier provided by the
220     *                                    programmer to recognise it's generated
221     *                                    html form
222     *  @param string $userData=null Array of contextual data optionally sent to the method.
223     *  The function must still function if none of it is present.
224     *
225     * This method understands:
226     *  $userData['preSelectedObject'] An optional Object of this class to be selected.
227     *  $userData['additionalWhere'] Additional SQL conditions for the
228     *                                    objects to select
229     *  $userData['allowEmpty'] boolean Allow not selecting any object
230     * @return string HTML markup
231
232     */
233    /**
234     * Get an interface to pick a network
235     *
236     * If there is only one network available, no interface is actually shown
237     *
238     * @param string $user_prefix          A identifier provided by the
239     *                                     programmer to recognise it's
240     *                                     generated html form
241     *
242     * @param string $userData=null Array of contextual data optionally sent to the method.
243     *  The function must still function if none of it is present.
244     *
245     * This method understands:
246     *  $userData['preSelectedObject'] An optional object to pre-select.
247     *  $userData['additionalWhere'] Additional SQL conditions for the
248     *                                    objects to select
249     *  $userData['allowEmpty'] boolean Allow not selecting any object
250     *  $userData['onlyNetwoksAllowingSignup'] boolean Only list networks allowing user self-signup
251     * @return string HTML markup
252
253     */
254    public static function getSelectUI($user_prefix, $userData=null)
255    {
256        $userData=$userData===null?array():$userData;
257        $html = '';
258        $name = $user_prefix;
259        //pretty_print_r($userData);
260        array_key_exists('preSelectedObject',$userData)?(empty($userData['preSelectedObject'])?$selected_id=null:$selected_id=$userData['preSelectedObject']->getId()):$selected_id=self::getDefaultNetwork()->getId();
261        !empty($userData['additionalWhere'])?$additional_where=$userData['additionalWhere']:$additional_where=null;
262        !empty($userData['allowEmpty'])?$allow_empty=$userData['allowEmpty']:$allow_empty=false;
263        !empty($userData['nullCaptionString'])?$nullCaptionString=$userData['nullCaptionString']:$nullCaptionString=null;
264        !empty($userData['onChange'])?$onChangeString=$userData['onChange']:$onChangeString="";
265        !empty($userData['onlyNetwoksAllowingSignup'])?$onlyNetwoksAllowingSignup=$userData['onlyNetwoksAllowingSignup']:$onlyNetwoksAllowingSignup=false;
266
267        $db = AbstractDb::getObject();
268        $sql = "SELECT network_id, name FROM networks WHERE 1=1 $additional_where";
269        $network_rows = null;
270        $db->execSql($sql, $network_rows, false);
271        if ($network_rows == null) {
272            throw new Exception(_("Network::getAllNetworks:  Fatal error: No networks in the database!"));
273        }
274
275        $number_of_networks = count($network_rows);
276        if ($number_of_networks > 1) {
277            $i = 0;
278            foreach ($network_rows as $network_row) {
279               
280                if($onlyNetwoksAllowingSignup==false || (self::getObject($network_row['network_id'])->getAuthenticator()->isRegistrationPermitted())==true){
281                    $tab[$i][0] = $network_row['network_id'];
282                    $tab[$i][1] = $network_row['name'];
283                    $i ++;
284                }
285            }
286            $html .= _("Network:")." \n";
287            $html .= FormSelectGenerator :: generateFromArray($tab, $selected_id, $name, null, $allow_empty, $nullCaptionString, "onchange='$onChangeString'");
288
289        } else {
290            foreach ($network_rows as $network_row) //iterates only once...
291            {
292                $html .= _("Network:")." \n";
293                $html .= " $network_row[name] ";
294                $html .= "<input type='hidden' name='$name' value='".htmlspecialchars($network_row['network_id'], ENT_QUOTES, 'UTF-8')."'>";
295            }
296        }
297
298        return $html;
299    }
300
301    /**
302     * Get the selected Network object.
303     *
304     * @param string $user_prefix A identifier provided by the programmer to
305     *                            recognise it's generated form
306     *
307     * @return mixed The network object or null
308
309     */
310    public static function processSelectUI($user_prefix)
311    {
312        $name = "{$user_prefix}";
313        if (!empty ($_REQUEST[$name])) {
314            return self::getObject($_REQUEST[$name]);
315        } else {
316            return null;
317        }
318    }
319
320    /**
321     * Get an interface to create a new network.
322     *
323     * @return string HTML markup
324     *
325     * @static
326     * @access public
327     */
328    public static function getCreateNewObjectUI()
329    {
330        // Init values
331        $html = '';
332
333        $html .= _("Create a new network with ID")." \n";
334        $name = "new_network_id";
335        $html .= "<input type='text' size='10' name='{$name}'>\n";
336        return $html;
337    }
338
339    /**
340     * Process the new object interface.
341     *
342     * Will return the new object if the user has the credentials and the form
343     * was fully filled.
344     *
345     * @return mixed The Network object or null if no new Network was created.
346     *
347     * @static
348     * @access public
349     */
350    public static function processCreateNewObjectUI()
351    {
352        // Init values
353        $retval = null;
354        $name = "new_network_id";
355
356        if (!empty($_REQUEST[$name])) {
357            $network_id = $_REQUEST[$name];
358
359            if (!preg_match('/^[0-9a-zA-Z_-]+$/', $network_id)) {
360            throw new Exception(_("The Network ID entered was not valid. It must only contain Alphanumerical Characters, Hyphens and Underscores e.g. My_Network-6"));
361            return;
362            }
363
364            if ($network_id) {
365                Security::requirePermission(Permission::P('SERVER_PERM_ADD_NEW_NETWORK'), Server::getServer());
366                $retval = self::createNewObject($network_id);
367            }
368        }
369
370        return $retval;
371    }
372
373    /**
374     * Constructor
375     *
376     * @param string $p_network_id
377     *
378     * @return void
379     *
380     * @access private
381     */
382    private function __construct($p_network_id)
383    {
384        $db = AbstractDb::getObject();
385        if ($p_network_id == "")
386            $p_network_id = self::getDefaultNetwork()->getId();
387        $network_id_str = $db->escapeString($p_network_id);
388
389        $sql = "SELECT *, EXTRACT(EPOCH FROM validation_grace_time) as validation_grace_time_seconds FROM networks WHERE network_id='$network_id_str'";
390        $row = null;
391        $db->execSqlUniqueRes($sql, $row, false);
392        if ($row == null) {
393            throw new Exception("The network with id $network_id_str could not be found in the database");
394        }
395        $this->_row = $row;
396        $this->_id = $p_network_id;
397        $this->_hotspotGraphElement = HotspotGraphElement::getObject($this->_id,'Network');
398    }
399
400    public function __toString()
401    {
402        return $this->getName();
403    }
404
405    /**
406     * Retreives the network name
407     *
408     * @return string The id
409     *
410     * @access public
411     */
412    public function getTechSupportEmail()
413    {
414        return $this->_row['tech_support_email'];
415    }
416
417    /**
418     * Set the network's tech support and information email address
419     *
420     * @param string $value The new value
421     *
422     * @return bool True on success, false on failure
423     *
424     * @access public
425     */
426    public function setTechSupportEmail($value)
427    {
428        // Init values
429        $retval = true;
430
431        if ($value != $this->getName()) {
432            $db = AbstractDb::getObject();
433            $value = $db->escapeString($value);
434            $retval = $db->execSqlUpdate("UPDATE networks SET tech_support_email = '{$value}' WHERE network_id = '{$this->getId()}'", false);
435            $this->refresh();
436        }
437
438        return $retval;
439    }
440
441    /**
442     * Retrieves the network name
443     *
444     * @return string A string
445     *
446     * @access public
447     */
448    public function getName()
449    {
450        return $this->_row['name'];
451    }
452
453    /**
454     * Set the network's name
455     *
456     * @param string $value The new value
457     *
458     * @return bool True on success, false on failure
459     *
460     * @access public
461     */
462    public function setName($value)
463    {
464        // Init values
465        $retval = true;
466
467        if ($value != $this->getName()) {
468            $db = AbstractDb::getObject();
469            $value = $db->escapeString($value);
470            $retval = $db->execSqlUpdate("UPDATE networks SET name = '{$value}' WHERE network_id = '{$this->getId()}'", false);
471            $this->refresh();
472        }
473
474        return $retval;
475    }
476
477    /**
478     * Retrieves the network's theme pack
479     *
480     * @return mixed ThemePack or null
481     *
482     * @access public
483     */
484    public function getThemePack()
485    {
486        if (!empty ($this->_row['theme_pack'])) {
487            return ThemePack::getObject($this->_row['theme_pack']);
488        } else {
489            return null;
490        }
491    }
492
493    /**
494     * Set the network's name
495     *
496     * @param string $value The new ThemePack, or null
497     *
498     * @return bool True on success, false on failure
499     *
500     * @access public
501     */
502    public function setThemePack($value)
503    {
504        // Init values
505        $retval = true;
506
507        if ($value != $this->getThemePack()) {
508            $db = AbstractDb::getObject();
509            empty($value)?$value="NULL":$value="'".$db->escapeString($value->getId())."'";
510            $retval = $db->execSqlUpdate("UPDATE networks SET theme_pack = {$value} WHERE network_id = '{$this->getId()}'", false);
511            $this->refresh();
512        }
513
514        return $retval;
515    }
516
517    /**
518     * Retrieves the network's creation date
519     *
520     * @return string Network's creation date
521     *
522     * @access public
523     */
524    public function getCreationDate()
525    {
526        return $this->_row['creation_date'];
527    }
528
529    /**
530     * Set the network's creation date
531     *
532     * @param string $value The new creation date
533     *
534     * @return bool True on success, false on failure
535     */
536    public function setCreationDate($value)
537    {
538
539        $db = AbstractDb::getObject();
540
541        // Init values
542        $retVal = true;
543
544        if ($value != $this->getCreationDate()) {
545            $value = $db->escapeString($value);
546            $retVal = $db->execSqlUpdate("UPDATE networks SET creation_date = '{$value}' WHERE network_id = '{$this->getId()}'", false);
547            $this->refresh();
548        }
549
550        return $retVal;
551    }
552
553    /**
554     * Retreives the network's homepage url
555     *
556     * @return string The id
557     *
558     * @access public
559     */
560    public function getWebSiteURL()
561    {
562        return $this->_row['homepage_url'];
563    }
564
565    /**
566     * Set the network's homepage url
567     *
568     * @param string $value The new value
569     *
570     * @return bool True on success, false on failure
571     *
572     * @access public
573     */
574    public function setWebSiteUrl($value)
575    {
576        // Init values
577        $retval = true;
578
579        if ($value != $this->getName()) {
580            $db = AbstractDb::getObject();
581            $value = $db->escapeString($value);
582            $retval = $db->execSqlUpdate("UPDATE networks SET homepage_url = '{$value}' WHERE network_id = '{$this->getId()}'", false);
583            $this->refresh();
584        }
585
586        return $retval;
587    }
588
589    /**
590     * Retreives the network's authenticator's class name.
591     *
592     * @return string Name of authenticator's class
593     */
594    public function getAuthenticatorClassName()
595    {
596        return $this->_row['network_authenticator_class'];
597    }
598
599    /**
600     * Set the network's authenticator's class.
601     *
602     * The subclass of Authenticator to be used for user authentication
603     * (ex: AuthenticatorRadius)
604     *
605     * @param string $value The class name of a  subclass of Authenticator
606     *
607     * @return bool True on success, false on failure
608     */
609    public function setAuthenticatorClassName($value)
610    {
611
612        $db = AbstractDb::getObject();
613
614        // Init values
615        $retval = true;
616
617        if ($value != $this->getAuthenticatorClassName()) {
618            $value = $db->escapeString($value);
619            $retval = $db->execSqlUpdate("UPDATE networks SET network_authenticator_class = '{$value}' WHERE network_id = '{$this->getId()}'", false);
620            $this->refresh();
621        }
622
623        return $retval;
624    }
625
626    /**
627     * Retreives the authenticator's parameters
628     *
629     * @return string Authenticator's parameters
630     */
631    public function getAuthenticatorConstructorParams()
632    {
633        return $this->_row['network_authenticator_params'];
634    }
635
636    /**
637     * The explicit parameters to be passed to the authenticator's constructor
638     * (ex: 'my_network_id', '192.168.0.11', 1812, 1813, 'secret_key',
639     * 'CHAP_MD5')
640     *
641     * @param string $value The new value
642     *
643     * @return bool True on success, false on failure
644     */
645    public function setAuthenticatorConstructorParams($value)
646    {
647
648        $db = AbstractDb::getObject();
649
650        // init values
651        $retval = true;
652
653        if ($value != $this->getAuthenticatorConstructorParams()) {
654            $value = $db->escapeString($value);
655            $retval = $db->execSqlUpdate("UPDATE networks SET network_authenticator_params = '{$value}' WHERE network_id = '{$this->getId()}'", false);
656            $this->refresh();
657        }
658
659        return $retval;
660    }
661
662    /**
663     * Get the Authenticator object for this network
664     *
665     * @return object A subclass of Authenticator
666     */
667    public function getAuthenticator()
668    {
669        require_once ('classes/Authenticator.php');
670
671        // Include only the authenticator we are about to use
672        require_once ("classes/Authenticators/".$this->_row['network_authenticator_class'].".php");
673
674        if (strpos($this->_row['network_authenticator_params'], ';') != false) {
675            throw new Exception("Network::getAuthenticator(): Security error: The parameters passed to the constructor of the authenticator are potentially unsafe");
676        }
677
678        $string=$this->_row['network_authenticator_params'];
679         
680        $params = explode(',', $string);
681        for ($i = 0; $i < count($params); $i++) {
682            $nquotes = substr_count($params[$i], '\'');
683            if ($nquotes %2 == 1) {
684                for ($j = $i+1; $j < count($params); $j++) {
685                    if (substr_count($params[$j], '\'') > 0) {
686                        array_splice($params, $i, $j-$i+1,
687                        implode(',', array_slice($params, $i, $j-$i+1)));
688                        break;
689                    }
690                }
691            }
692            if ($nquotes > 0) {
693                $qstr =& $params[$i];
694                $qstr = substr_replace($qstr, '', strpos($qstr, '\''), 1);
695                $qstr = substr_replace($qstr, '', strrpos($qstr, '\''), 1);
696            }
697        }
698        return call_user_func_array(array (new ReflectionClass($this->_row['network_authenticator_class']), 'newInstance'), $params);
699
700    }
701
702    /**
703     * Get the list of available Authenticators on the system
704     *
705     * @return array An array of class names
706
707     */
708    public static function getAvailableAuthenticators()
709    {
710        // Init values
711        $authenticators = array ();
712        $useCache = false;
713        $cachedData = null;
714
715        // Create new cache object with a lifetime of one week
716        $cache = new Cache("AuthenticatorClasses", "ClassFileCaches", 604800);
717
718        // Check if caching has been enabled.
719        if ($cache->isCachingEnabled) {
720            $cachedData = $cache->getCachedData("mixed");
721
722            if ($cachedData) {
723                // Return cached data.
724                $useCache = true;
725                $authenticators = $cachedData;
726            }
727        }
728
729        if (!$useCache) {
730            $dir = WIFIDOG_ABS_FILE_PATH."classes/Authenticators";
731            $dirHandle = @ opendir($dir);
732
733            if ($dirHandle) {
734                // Loop over the directory
735                while (false !== ($filename = readdir($dirHandle))) {
736                    // Loop through sub-directories of Content
737                    if ($filename != '.' && $filename != '..') {
738                        $matches = null;
739
740                        if (preg_match("/^(.*)\.php$/", $filename, $matches) > 0) {
741                            // Only add files containing a corresponding Authenticator class
742                            if (is_file("{$dir}/{$matches[0]}")) {
743                                $authenticators[] = $matches[1];
744                            }
745                        }
746                    }
747                }
748
749                closedir($dirHandle);
750            }
751            else {
752                throw new Exception(_('Unable to open directory ').$dir);
753            }
754
755            // Sort the result array
756            sort($authenticators);
757
758            // Check if caching has been enabled.
759            if ($cache->isCachingEnabled) {
760                // Save results into cache, because it wasn't saved into cache before.
761                $cache->saveCachedData($authenticators, "mixed");
762            }
763        }
764
765        return $authenticators;
766    }
767
768    /**
769     * Get an interface to pick an Authenticator
770     *
771     * @param string $user_prefix                A identifier provided by the
772     *                                           programmer to recognise it's
773     *                                           generated html form
774     * @param string $pre_selected_authenticator The Authenticator to be
775     *                                           pre-selected in the form object
776     *
777     * @return string HTML markup
778
779     */
780    public static function getSelectAuthenticator($user_prefix, $pre_selected_authenticator = null)
781    {
782
783        $db = AbstractDb::getObject();
784
785        // Init values
786        $authenticators = array ();
787
788        foreach (self :: getAvailableAuthenticators() as $authenticator) {
789            $authenticators[] = array ($authenticator, $authenticator);
790        }
791
792        $name = $user_prefix;
793
794        if ($pre_selected_authenticator) {
795            $selectedID = $pre_selected_authenticator;
796        }
797        else {
798            $selectedID = null;
799        }
800
801        $html = FormSelectGenerator :: generateFromArray($authenticators, $selectedID, $name, null, false);
802
803        return $html;
804    }
805
806    /**
807     * Is the network the default network?
808     *
809     * @return bool True or false
810     *
811     * @access public
812     */
813    public function isDefaultNetwork()
814    {
815        (self::getDefaultNetwork()->getId() == $this->getId()) ? $retval = true : $retval = false;
816        return $retval;
817    }
818
819    /**
820     * Retreives the network's validation grace period
821     *
822     * @return int Network's validation grace period in seconds
823     *
824     * @access public
825     */
826    public function getValidationGraceTime()
827    {
828        return $this->_row['validation_grace_time_seconds'];
829    }
830
831    /**
832     * Set the network's validation grace period in seconds.
833     *
834     * A new user is granted Internet access for this period check his email
835     * and validate his account.
836     *
837     * @param int $value The new value
838     *
839     * @return bool True on success, false on failure
840     *
841     * @access public
842     */
843    public function setValidationGraceTime($value)
844    {
845        // Init values
846        $retval = true;
847
848        if ($value != $this->getValidationGraceTime()) {
849            $db = AbstractDb::getObject();
850            $value = $db->escapeString($value);
851            $retval = $db->execSqlUpdate("UPDATE networks SET validation_grace_time = '{$value} seconds' WHERE network_id = '{$this->getId()}'", false);
852            $this->refresh();
853        }
854
855        return $retval;
856    }
857
858    /**
859     * Retreives the FROM address of the validation email
860     *
861     * @return string A string
862     *
863     * @access public
864     */
865    public function getValidationEmailFromAddress()
866    {
867        return $this->_row['validation_email_from_address'];
868    }
869
870    /**
871     * Set the FROM address of the validation email
872     *
873     * @param string $value The new value
874     *
875     * @return bool True on success, false on failure
876     *
877     * @access public
878     */
879    public function setValidationEmailFromAddress($value)
880    {
881        // Init values
882        $retval = true;
883
884        if ($value != $this->getValidationEmailFromAddress()) {
885            $db = AbstractDb::getObject();
886            $value = $db->escapeString($value);
887            $retval = $db->execSqlUpdate("UPDATE networks SET validation_email_from_address = '{$value}' WHERE network_id = '{$this->getId()}'", false);
888            $this->refresh();
889        }
890
891        return $retval;
892    }
893
894    /**
895     * Can an account be connected more than once at the same time?
896     *
897     * @return bool True or false
898     *
899     * @access public
900     */
901    public function getMultipleLoginAllowed()
902    {
903        return ($this->_row['allow_multiple_login'] == 't') ? true : false;
904    }
905
906    /**
907     * Set if a account be connected more than once at the same time
908     *
909     * @param bool $value The new value, true or false
910     *
911     * @return bool true on success, false on failure
912     *
913     * @access public
914     */
915    public function setMultipleLoginAllowed($value)
916    {
917        // Init values
918        $retval = true;
919
920        if ($value != $this->getMultipleLoginAllowed()) {
921            $db = AbstractDb::getObject();
922            $value ? $value = 'TRUE' : $value = 'FALSE';
923            $retval = $db->execSqlUpdate("UPDATE networks SET allow_multiple_login = {$value} WHERE network_id = '{$this->getId()}'", false);
924            $this->refresh();
925        }
926
927        return $retval;
928    }
929
930    /**
931     * Are nodes allowed to be set as splash-only (no login)?
932     *
933     * @return bool True or false
934     *
935     * @access public
936     */
937    public function getSplashOnlyNodesAllowed()
938    {
939        return (($this->_row['allow_splash_only_nodes'] == 't') ? true : false);
940    }
941
942    /**
943     * Set if nodes are allowed to be set as splash-only (no login)
944     *
945     * @param bool $value The new value, true or false
946     *
947     * @return bool True on success, false on failure
948     *
949     * @access public
950     */
951    public function setSplashOnlyNodesAllowed($value)
952    {
953        // Init values
954        $retval = true;
955
956        if ($value != $this->getSplashOnlyNodesAllowed()) {
957            $db = AbstractDb::getObject();
958            $value ? $value = 'TRUE' : $value = 'FALSE';
959            $retval = $db->execSqlUpdate("UPDATE networks SET allow_splash_only_nodes = {$value} WHERE network_id = '{$this->getId()}'", false);
960            $this->refresh();
961        }
962
963        return $retval;
964    }
965
966    /**
967     * Get a GisPoint object
968     *
969     * @return object GisPoint object
970     */
971    public function getGisLocation()
972    {
973        return new GisPoint($this->_row['gmaps_initial_latitude'], $this->_row['gmaps_initial_longitude'], $this->_row['gmaps_initial_zoom_level']);
974    }
975
976    /**
977     * Set the network's GisPoint object
978     *
979     * @param $value The new GisPoint object
980     *
981     * @return bool True on success, false on failure
982     */
983    public function setGisLocation($pt)
984    {
985        $retval=false;
986        $db = AbstractDb::getObject();
987
988        if (!empty ($pt)) {
989            $lat = $db->escapeString($pt->getLatitude());
990            $long = $db->escapeString($pt->getLongitude());
991            $alt = $db->escapeString($pt->getAltitude());
992
993            if (!empty ($lat) && !empty ($long) && !empty ($alt)) {
994                $db->execSqlUpdate("UPDATE networks SET gmaps_initial_latitude = $lat, gmaps_initial_longitude = $long, gmaps_initial_zoom_level = $alt WHERE network_id = '{$this->getId()}'");
995                $retval=true;
996            }
997            else {
998                $db->execSqlUpdate("UPDATE networks SET gmaps_initial_latitude = NULL, gmaps_initial_longitude = NULL, gmaps_initial_zoom_level = NULL WHERE network_id = '{$this->getId()}'");
999            }
1000            $this->refresh();
1001        }
1002        return $retval;
1003    }
1004
1005    /**
1006     * Retreives the default Google maps type
1007     *
1008     * @return string Default Google maps type
1009     */
1010    public function getGisMapType()
1011    {
1012        return $this->_row['gmaps_map_type'];
1013    }
1014
1015    /**
1016     * Set the network's default Google maps type
1017     *
1018     * @param $value The new default Google maps type
1019     *
1020     * @return bool True on success, false on failure
1021     */
1022    public function setGisMapType($value)
1023    {
1024
1025        $db = AbstractDb::getObject();
1026
1027        // Init values
1028        $retval = true;
1029
1030        if ($value != $this->getGisMapType()) {
1031            $value = $db->escapeString($value);
1032            $retval = $db->execSqlUpdate("UPDATE networks SET gmaps_map_type = '{$value}' WHERE network_id = '{$this->getId()}'", false);
1033            $this->refresh();
1034        }
1035        return $retval;
1036    }
1037
1038    /**
1039     * Get an interface to pick a Google maps type
1040     *
1041     * @param string $user_prefix           A identifier provided by the
1042     *                                      programmer to recognise it's
1043     *                                      generated html form
1044     * @param string $pre_selected_map_type The Google map type to be
1045     *                                      pre-selected in the form object
1046     *
1047     * @return string HTML markup
1048
1049     */
1050    public static function getSelectGisMapType($user_prefix, $pre_selected_map_type = "G_NORMAL_MAP")
1051    {
1052
1053        $db = AbstractDb::getObject();
1054
1055        // Init values
1056        $map_types = array (array ("G_NORMAL_MAP", _("Map")), array ("G_SATELLITE_MAP", _("Satellite")), array ("G_HYBRID_MAP", _("Hybrid")));
1057
1058        $name = $user_prefix;
1059
1060        if ($pre_selected_map_type) {
1061            $selectedID = $pre_selected_map_type;
1062        }
1063        else {
1064            $selectedID = null;
1065        }
1066
1067        $html = FormSelectGenerator :: generateFromArray($map_types, $selectedID, $name, null, false);
1068
1069        return $html;
1070    }
1071
1072    /**
1073     * Get's the splash-only user.
1074     *
1075     * This is the user that people logged-in at a splash-only hotspot will
1076     * show up as.  This user always has multiple-login capabilities.
1077     *
1078     * @param string $username The username of the user
1079     * @param string $account_origin The account origin
1080     *
1081     * @return object A User object
1082     *
1083     * @access public
1084     */
1085    public function getSplashOnlyUser()
1086    {
1087        $username = 'SPLASH_ONLY_USER';
1088        if(!empty($this->splashOnlyUser)) {
1089            $user = $this->splashOnlyUser;
1090        }
1091        else
1092        {
1093            $user = User :: getUserByUsernameAndOrigin($username, $this);
1094            if (!$user) {
1095                $user = User :: createUser(get_guid(), $username, $this, '', '');
1096                $user->setAccountStatus(ACCOUNT_STATUS_ALLOWED);
1097            }
1098            $this->splashOnlyUser = $user;
1099        }
1100        return $user;
1101    }
1102
1103    /**
1104     * Find out the total number of users in this networks's database
1105     *
1106     * @return int Number of users
1107     */
1108    public function getNumUsers()
1109    {
1110
1111        $db = AbstractDb::getObject();
1112
1113        // Init values
1114        $retval = 0;
1115        $row = null;
1116        $useCache = false;
1117        $cachedData = null;
1118
1119        // Create new cache objects (valid for 1 minute)
1120        $cache = new Cache('network_'.$this->_id.'_num_users', $this->_id, 60);
1121
1122        // Check if caching has been enabled.
1123        if ($cache->isCachingEnabled) {
1124            $cachedData = $cache->getCachedData();
1125
1126            if ($cachedData) {
1127                // Return cached data.
1128                $useCache = true;
1129                $retval = $cachedData;
1130            }
1131        }
1132
1133        if (!$useCache) {
1134            // Get number of users
1135            $network_id = $db->escapeString($this->_id);
1136            $db->execSqlUniqueRes("SELECT COUNT(user_id) FROM users WHERE account_origin='$network_id'", $row, false);
1137
1138            // String has been found
1139            $retval = $row['count'];
1140
1141            // Check if caching has been enabled.
1142            if ($cache->isCachingEnabled) {
1143                // Save data into cache, because it wasn't saved into cache before.
1144                $cache->saveCachedData($retval);
1145            }
1146        }
1147
1148        return $retval;
1149    }
1150
1151    /**
1152     * Find out how many users are valid in this networks's database
1153     *
1154     * @return int Number of valid users
1155     */
1156    public function getNumValidUsers()
1157    {
1158
1159        $db = AbstractDb::getObject();
1160
1161        // Init values
1162        $retval = 0;
1163        $row = null;
1164        $useCache = false;
1165        $cachedData = null;
1166
1167        // Create new cache objects (valid for 1 minute)
1168        $cache = new Cache('network_'.$this->_id.'_num_valid_users', $this->_id, 60);
1169
1170        // Check if caching has been enabled.
1171        if ($cache->isCachingEnabled) {
1172            $cachedData = $cache->getCachedData();
1173
1174            if ($cachedData) {
1175                // Return cached data.
1176                $useCache = true;
1177                $retval = $cachedData;
1178            }
1179        }
1180
1181        if (!$useCache) {
1182            // Get number of valid users
1183            $network_id = $db->escapeString($this->_id);
1184            $db->execSqlUniqueRes("SELECT COUNT(user_id) FROM users WHERE account_status = ".ACCOUNT_STATUS_ALLOWED." AND account_origin='$network_id'", $row, false);
1185            // String has been found
1186            $retval = $row['count'];
1187
1188            // Check if caching has been enabled.
1189            if ($cache->isCachingEnabled) {
1190                // Save data into cache, because it wasn't saved into cache before.
1191                $cache->saveCachedData($retval);
1192            }
1193        }
1194
1195        return $retval;
1196    }
1197
1198    /**
1199     * Find out how many users are connected on the entire network
1200     * Counts every user account connected (once for every account), except the splash-only user + every mac adresses connecting as the splash-only user
1201     * @return int Number of online users
1202     */
1203    public function getNumOnlineUsers()
1204    {
1205
1206        $db = AbstractDb::getObject();
1207
1208        // Init values
1209        $retval = 0;
1210        $row = null;
1211        $useCache = false;
1212        $cachedData = null;
1213
1214        // Create new cache objects (valid for 1 minute)
1215        $cache = new Cache('network_'.$this->_id.'_num_online_users', $this->_id, 60);
1216
1217        // Check if caching has been enabled.
1218        if ($cache->isCachingEnabled) {
1219            $cachedData = $cache->getCachedData();
1220
1221            if ($cachedData) {
1222                // Return cached data.
1223                $useCache = true;
1224                $retval = $cachedData;
1225            }
1226        }
1227
1228        if (!$useCache) {
1229            // Get number of online users
1230            $network_id = $db->escapeString($this->_id);
1231            $splashOnlyUserId = $this->getSplashOnlyUser()->getId();
1232            $sql = "SELECT ((SELECT COUNT(DISTINCT users.user_id) as count FROM users,connections JOIN tokens USING (token_id) NATURAL JOIN nodes JOIN networks ON (nodes.network_id=networks.network_id AND networks.network_id='$network_id') WHERE tokens.token_status='".TOKEN_INUSE."' AND users.user_id=connections.user_id AND users.user_id!='{$splashOnlyUserId}') + (SELECT COUNT(DISTINCT connections.user_mac) as count FROM users,connections JOIN tokens USING (token_id) NATURAL JOIN nodes JOIN networks ON (nodes.network_id=networks.network_id AND networks.network_id='$network_id') WHERE tokens.token_status='".TOKEN_INUSE."' AND users.user_id=connections.user_id AND users.user_id='{$splashOnlyUserId}')) AS count";
1233            $db->execSqlUniqueRes($sql, $row, false);
1234
1235            $retval = $row['count'];
1236
1237            // Check if caching has been enabled.
1238            if ($cache->isCachingEnabled) {
1239                // Save data into cache, because it wasn't saved into cache before.
1240                $cache->saveCachedData($retval);
1241            }
1242        }
1243
1244        return $retval;
1245    }
1246
1247    /**
1248     * Find out how many nodes are registered in this networks's database
1249     *
1250     * @return int Number of nodes
1251     */
1252    public function getNumNodes()
1253    {
1254
1255        $db = AbstractDb::getObject();
1256
1257        // Init values
1258        $retval = 0;
1259        $row = null;
1260        $useCache = false;
1261        $cachedData = null;
1262
1263        // Create new cache objects (valid for 5 minutes)
1264        $cache = new Cache('network_'.$this->_id.'_num_nodes', $this->_id, 300);
1265
1266        // Check if caching has been enabled.
1267        if ($cache->isCachingEnabled) {
1268            $cachedData = $cache->getCachedData();
1269
1270            if ($cachedData) {
1271                // Return cached data.
1272                $useCache = true;
1273                $retval = $cachedData;
1274            }
1275        }
1276
1277        if (!$useCache) {
1278            // Get number of nodes
1279            $network_id = $db->escapeString($this->_id);
1280            $db->execSqlUniqueRes("SELECT COUNT(node_id) FROM nodes WHERE network_id = '$network_id'", $row, false);
1281
1282            // String has been found
1283            $retval = $row['count'];
1284
1285            // Check if caching has been enabled.
1286            if ($cache->isCachingEnabled) {
1287                // Save data into cache, because it wasn't saved into cache before.
1288                $cache->saveCachedData($retval);
1289            }
1290        }
1291
1292        return $retval;
1293    }
1294
1295    /**
1296     * Find out how many nodes are deployed in this networks's database
1297     *
1298     * @return int Number of deployed nodes
1299     */
1300    public function getNumDeployedNodes()
1301    {
1302
1303        $db = AbstractDb::getObject();
1304
1305        // Init values
1306        $retval = 0;
1307        $row = null;
1308        $useCache = false;
1309        $cachedData = null;
1310
1311        // Create new cache objects (valid for 5 minutes)
1312        $cache = new Cache('network_'.$this->_id.'_num_deployed_nodes', $this->_id, 300);
1313
1314        // Check if caching has been enabled.
1315        if ($cache->isCachingEnabled) {
1316            $cachedData = $cache->getCachedData();
1317
1318            if ($cachedData) {
1319                // Return cached data.
1320                $useCache = true;
1321                $retval = $cachedData;
1322            }
1323        }
1324
1325        if (!$useCache) {
1326            // Get number of deployed nodes
1327            $network_id = $db->escapeString($this->_id);
1328            $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);
1329
1330            // String has been found
1331            $retval = $row['count'];
1332
1333            // Check if caching has been enabled.
1334            if ($cache->isCachingEnabled) {
1335                // Save data into cache, because it wasn't saved into cache before.
1336                $cache->saveCachedData($retval);
1337            }
1338        }
1339
1340        return $retval;
1341    }
1342
1343    /**
1344     * Find out how many deployed nodes are online in this networks's database
1345     *
1346     * @param bool $nonMonitoredOnly Return number of non-monitored nodes only
1347     *
1348     * @return int Number of deployed nodes which are online
1349     */
1350    public function getNumOnlineNodes($nonMonitoredOnly = false)
1351    {
1352
1353        $db = AbstractDb::getObject();
1354
1355        // Init values
1356        $retval = 0;
1357        $row = null;
1358        $useCache = false;
1359        $cachedData = null;
1360
1361        // Create new cache objects (valid for 5 minutes)
1362        if ($nonMonitoredOnly) {
1363            $cache = new Cache('network_'.$this->_id.'_num_online_nodes_non_monitored', $this->_id, 300);
1364        } else {
1365            $cache = new Cache('network_'.$this->_id.'_num_online_nodes', $this->_id, 300);
1366        }
1367
1368        // Check if caching has been enabled.
1369        if ($cache->isCachingEnabled) {
1370            $cachedData = $cache->getCachedData();
1371
1372            if ($cachedData) {
1373                // Return cached data.
1374                $useCache = true;
1375                $retval = $cachedData;
1376            }
1377        }
1378
1379        if (!$useCache) {
1380            // Get number of online nodes
1381            $network_id = $db->escapeString($this->_id);
1382
1383            if ($nonMonitoredOnly) {
1384                $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);
1385            } else {
1386                $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);
1387            }
1388
1389            // String has been found
1390            $retval = $row['count'];
1391
1392            // Check if caching has been enabled.
1393            if ($cache->isCachingEnabled) {
1394                // Save data into cache, because it wasn't saved into cache before.
1395                $cache->saveCachedData($retval);
1396            }
1397        }
1398
1399        return $retval;
1400    }
1401
1402    /**
1403     * Are nodes allowed to redirect users to an arbitrary web page instead of
1404     * the portal?
1405     *
1406     * @return bool True or false
1407     *
1408     * @access public
1409     */
1410    public function getCustomPortalRedirectAllowed()
1411    {
1412        return (($this->_row['allow_custom_portal_redirect'] == 't') ? true : false);
1413    }
1414
1415    /**
1416     * Set if nodes are allowed to redirect users to an arbitrary web page
1417     * instead of the portal?
1418     *
1419     * @param bool $value The new value, true or false
1420     *
1421     * @return bool True on success, false on failure
1422     *
1423     * @access public
1424     */
1425    public function setCustomPortalRedirectAllowed($value)
1426    {
1427        // Init values
1428        $retval = true;
1429
1430        if ($value != $this->getCustomPortalRedirectAllowed()) {
1431            $db = AbstractDb::getObject();
1432            $value ? $value = 'TRUE' : $value = 'FALSE';
1433            $retval = $db->execSqlUpdate("UPDATE networks SET allow_custom_portal_redirect = {$value} WHERE network_id = '{$this->getId()}'", false);
1434            $this->refresh();
1435        }
1436
1437        return $retval;
1438    }
1439
1440    /**
1441     * Are nodes allowed to redirect users to the original requested web page instead of
1442     * the portal?
1443     *
1444     * @return bool True or false
1445     *
1446     * @access public
1447     */
1448    public function getPortalOriginalUrlAllowed()
1449    {
1450        return (($this->_row['allow_original_url_redirect'] == 't') ? true : false);
1451    }
1452
1453    /**
1454     * Set if nodes are allowed to redirect users to the original requested web page
1455     * instead of the portal?
1456     *
1457     * @param bool $value The new value, true or false
1458     *
1459     * @return bool True on success, false on failure
1460     *
1461     * @access public
1462     */
1463    public function setPortalOriginalUrlAllowed($value)
1464    {
1465        // Init values
1466        $retval = true;
1467
1468        if ($value != $this->getPortalOriginalUrlAllowed()) {
1469            $db = AbstractDb::getObject();
1470            $value ? $value = 'TRUE' : $value = 'FALSE';
1471            $retval = $db->execSqlUpdate("UPDATE networks SET allow_original_url_redirect = {$value} WHERE network_id = '{$this->getId()}'", false);
1472            $this->refresh();
1473        }
1474
1475        return $retval;
1476    }
1477
1478
1479    /** The length of the window during which the user must not have exceeded the limits below.
1480     *
1481     * @return string Interval as returned by postgresql
1482     */
1483    public function getConnectionLimitWindow()
1484    {
1485        return $this->_row['connection_limit_window'];
1486    }
1487
1488    /**
1489     * Set the network's creation date
1490     *
1491     * @param string $value The new creation date
1492     *
1493     * @return bool True on success, false on failure
1494     */
1495    public function setConnectionLimitWindow($value)
1496    {
1497        $db = AbstractDb::getObject();
1498        // Init values
1499        $retVal = true;
1500
1501        if ($value != $this->getConnectionLimitWindow()) {
1502            $value?$value_sql="'".$db->escapeString($value)."'":$value_sql="NULL";
1503            $retVal = $db->execSqlUpdate("UPDATE networks SET connection_limit_window = $value_sql WHERE network_id = '{$this->getId()}'", false);
1504            $this->refresh();
1505        }
1506        return $retVal;
1507    }
1508
1509    /** Maximum data transfer during the abuse control window, in bytes
1510     *
1511     * @return integer Number of bytes
1512     */
1513    public function getConnectionLimitNetworkMaxTotalBytes()
1514    {
1515        return $this->_row['connection_limit_network_max_total_bytes'];
1516    }
1517
1518    /**
1519     * Maximum data transfer during the abuse control window, in bytes
1520     *
1521     * @param $value integer Number of bytes
1522     *
1523     * @return bool True on success, false on failure
1524     */
1525    public function setConnectionLimitNetworkMaxTotalBytes($value)
1526    {
1527        $db = AbstractDb::getObject();
1528        // Init values
1529        $retVal = true;
1530
1531        if ($value != $this->getConnectionLimitNetworkMaxTotalBytes()) {
1532            $value?$value_sql="'".$db->escapeString($value)."'":$value_sql="NULL";
1533            $retVal = $db->execSqlUpdate("UPDATE networks SET connection_limit_network_max_total_bytes = $value_sql WHERE network_id = '{$this->getId()}'", false);
1534            $this->refresh();
1535        }
1536        return $retVal;
1537    }
1538
1539    /** Maximum connection duration during the abuse control window
1540     *
1541     * @return string Interval as returned by postgresql
1542     */
1543    public function getConnectionLimitNetworkMaxDuration()
1544    {
1545        return $this->_row['connection_limit_network_max_usage_duration'];
1546    }
1547
1548    /** Maximum connection duration during the abuse control window
1549     *
1550     * @param string $value The new creation date
1551     *
1552     * @return bool True on success, false on failure
1553     */
1554    public function setConnectionLimitNetworkMaxDuration($value)
1555    {
1556        $db = AbstractDb::getObject();
1557        // Init values
1558        $retVal = true;
1559
1560        if ($value != $this->getConnectionLimitNetworkMaxDuration()) {
1561            $value?$value_sql="'".$db->escapeString($value)."'":$value_sql="NULL";
1562            $retVal = $db->execSqlUpdate("UPDATE networks SET connection_limit_network_max_usage_duration = $value_sql WHERE network_id = '{$this->getId()}'", false);
1563            $this->refresh();
1564        }
1565        return $retVal;
1566    }
1567
1568    /** Maximum data transfer during the abuse control window, in bytes
1569     *
1570     * @return integer Number of bytes
1571     */
1572    public function getConnectionLimitNodeMaxTotalBytes()
1573    {
1574        return $this->_row['connection_limit_node_max_total_bytes'];
1575    }
1576
1577    /**
1578     * Maximum data transfer during the abuse control window, in bytes
1579     *
1580     * @param $value integer Number of bytes
1581     *
1582     * @return bool True on success, false on failure
1583     */
1584    public function setConnectionLimitNodeMaxTotalBytes($value)
1585    {
1586        $db = AbstractDb::getObject();
1587        // Init values
1588        $retVal = true;
1589
1590        if ($value != $this->getConnectionLimitNodeMaxTotalBytes()) {
1591            $value?$value_sql="'".$db->escapeString($value)."'":$value_sql="NULL";
1592            $retVal = $db->execSqlUpdate("UPDATE networks SET connection_limit_node_max_total_bytes = $value_sql WHERE network_id = '{$this->getId()}'", false);
1593            $this->refresh();
1594        }
1595        return $retVal;
1596    }
1597
1598    /** Maximum connection duration during the abuse control window
1599     *
1600     * @return string Interval as returned by postgresql
1601     */
1602    public function getConnectionLimitNodeMaxDuration()
1603    {
1604        return $this->_row['connection_limit_node_max_usage_duration'];
1605    }
1606
1607    /** Maximum connection duration during the abuse control window
1608     *
1609     * @param string $value The new creation date
1610     *
1611     * @return bool True on success, false on failure
1612     */
1613    public function setConnectionLimitNodeMaxDuration($value)
1614    {
1615        $db = AbstractDb::getObject();
1616        // Init values
1617        $retVal = true;
1618
1619        if ($value != $this->getConnectionLimitNodeMaxDuration()) {
1620            $value?$value_sql="'".$db->escapeString($value)."'":$value_sql="NULL";
1621            $retVal = $db->execSqlUpdate("UPDATE networks SET connection_limit_node_max_usage_duration = $value_sql WHERE network_id = '{$this->getId()}'", false);
1622            $this->refresh();
1623        }
1624        return $retVal;
1625    }
1626   
1627          /** Are usernames on this network case sensitive or not
1628     *
1629     * @return bool true or false
1630     */
1631    public function getUsernamesCaseSensitive()
1632    {
1633        return (($this->_row['usernames_case_sensitive'] == 't') ? true : false);
1634    }
1635
1636    /** Are usernames on this network case sensitive or not
1637     * If set to false, we need to verify if some users have name-clash and propose actions
1638     *
1639     * @param string $value The new creation date
1640     *
1641     * @return bool True on success, false on failure
1642     */
1643    public function setUsernamesCaseSensitive($value)
1644    {
1645        // Init values
1646        $retval = true;
1647
1648        if ($value != $this->getUsernamesCaseSensitive()) {
1649            $db = AbstractDb::getObject();
1650            // Verify if usernames differing by case exists
1651            if (!$value) {
1652                $sql = "Select username, email from users where
1653                    lower(username) in (Select lower(username) as uname from users where account_origin = '{$this->getId()}' group by lower(username) having count(user_id) > 1)
1654                    or lower(email) in (Select lower(email) from users where account_origin = '{$this->getId()}' group by lower(email) having count(user_id) > 1) order by username";
1655                if (!$db->execSql($sql, $duplicates)) 
1656                    $retval = false;
1657                if (!empty($duplicates)) {
1658                    $duplicatenames = array();
1659                    foreach($duplicates as $duplicate) $duplicatenames[] = "{$duplicate['username']} ({$duplicate['email']})";
1660                    $this->errorMsg = _("You cannot change the case sensitivity of this network because some users would have duplicate names or emails.  Some action must be performed before.<br/>Here is a list of duplicate usernames: " . implode(', ', $duplicatenames));
1661                    $retval = false;
1662                }
1663            }
1664            if ($retval) {
1665                $value ? $value = 'TRUE' : $value = 'FALSE';
1666                $retval = $db->execSqlUpdate("UPDATE networks SET usernames_case_sensitive = {$value} WHERE network_id = '{$this->getId()}'", false);
1667                $this->refresh();
1668            }
1669        }
1670
1671        return $retval;
1672    }
1673
1674
1675    /**
1676     * Retreives the admin interface of this object
1677     *
1678     * @return string The HTML fragment for this interface
1679     */
1680    public function getAdminUI()
1681    {
1682        Security::requirePermission(Permission::P('NETWORK_PERM_EDIT_NETWORK_CONFIG'), $this);
1683        require_once('classes/InterfaceElements.php');
1684        // Init values
1685        $html = '';
1686       
1687        /*
1688         * Verify if an error message was registered before outputting the form
1689         */
1690        if (isset($this->errorMsg)) {
1691             $html .= "<div class='errormsg'>" . $this->errorMsg . "</div>";
1692        }
1693
1694        /*
1695         * Begin with admin interface
1696         */
1697        $html .= "<fieldset class='admin_container ".get_class($this)."'>\n";
1698        $html .= "<legend>"._("Network management")."</legend>\n";
1699        $html .= "<ul class='admin_element_list'>\n";
1700
1701        /*
1702         * Content management
1703         */
1704       /* $title = _("Network content");
1705        $name = "network_".$this->_id."_content";
1706        $data = Content::getLinkedContentUI($name, "network_has_content", "network_id", $this->_id, $display_page = "portal");
1707        $html .= InterfaceElements::generateAdminSectionContainer("network_content", $title, $data);*/
1708        if (!is_null($this->_hotspotGraphElement))
1709            $html .= $this->_hotspotGraphElement->getContentAdminUI();
1710
1711        /*
1712         * Network information
1713         */
1714        $html_network_information = array();
1715
1716        // network_id
1717        $title = _("Network ID");
1718        $data = htmlspecialchars($this->getId(), ENT_QUOTES);
1719        $html_network_information[] = InterfaceElements::generateAdminSectionContainer("network_id", $title, $data);
1720
1721        // name
1722        $title = _("Network name");
1723        $data = InterfaceElements::generateInputText("network_" . $this->getId() . "_name", $this->getName(), "network_name_input");
1724        $html_network_information[] = InterfaceElements::generateAdminSectionContainer("network_name", $title, $data);
1725
1726        // creation_date
1727        $title = _("Network creation date");
1728        $data = DateTimeWD::getSelectDateTimeUI(new DateTimeWD($this->getCreationDate()), "network_" . $this->getId() . "_creation_date", DateTimeWD::INTERFACE_DATETIME_FIELD, "network_creation_date_input");
1729        $html_network_information[] = InterfaceElements::generateAdminSectionContainer("network_creation_date", $title, $data);
1730
1731        // homepage_url
1732        $title = _("Network's web site");
1733        $data = InterfaceElements::generateInputText("network_" . $this->getId() . "_homepage_url", $this->getWebSiteURL(), "network_homepage_url_input");
1734        $html_network_information[] = InterfaceElements::generateAdminSectionContainer("network_homepage_url", $title, $data);
1735
1736        // tech_support_email
1737        $title = _("Technical support email");
1738        $data = InterfaceElements::generateInputText("network_" . $this->getId() . "_tech_support_email", $this->getTechSupportEmail(), "network_tech_support_email_input");
1739        $html_network_information[] = InterfaceElements::generateAdminSectionContainer("network_tech_support_email", $title, $data);
1740
1741        // Build section
1742        $html .= InterfaceElements::generateAdminSectionContainer("network_information", _("Information about the network"), implode(null, $html_network_information));
1743
1744        /*
1745         * Network authentication
1746         */
1747        $html_network_authentication = array();
1748
1749        //  network_authenticator_class
1750        $title = _("Network authenticator class");
1751        $help = _("The subclass of Authenticator to be used for user authentication. Example: AuthenticatorRadius");
1752        $name = "network_" . $this->getId() . "_network_authenticator_class";
1753        $value = htmlspecialchars($this->getAuthenticatorClassName(), ENT_QUOTES);
1754        $data = $this->getSelectAuthenticator($name, $value);
1755        $html_network_authentication[] = InterfaceElements::generateAdminSectionContainer("network_network_authenticator_class", $title, $data, $help);
1756
1757        //  network_authenticator_params
1758        $title = _("Authenticator parameters");
1759        $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'");
1760        $data = InterfaceElements::generateInputText("network_" . $this->getId() . "_network_authenticator_params", $this->getAuthenticatorConstructorParams(), "network_network_authenticator_params_input");
1761        $html_network_authentication[] = InterfaceElements::generateAdminSectionContainer("network_network_authenticator_params", $title, $data, $help);
1762
1763        // Build section
1764        $html .= InterfaceElements::generateAdminSectionContainer("network_authentication", _("Network Authentication"), implode(null, $html_network_authentication));
1765
1766        /*
1767         * Network properties
1768         */
1769        $html_network_properties = array();
1770
1771        //  theme_pack
1772        $title = _("Selected theme pack for this network");
1773        $data = ThemePack::getSelectUI("network_" . $this->getId() . "_theme_pack", $this->getThemePack());
1774        $html_network_properties[] = InterfaceElements::generateAdminSectionContainer("network_theme_pack", $title, $data);
1775     
1776        // Build section
1777        $html .= InterfaceElements::generateAdminSectionContainer("network_properties", _("Network properties"), implode(null, $html_network_properties));
1778
1779        /*
1780         * Network's node properties
1781         */
1782        $html_network_node_properties = array();
1783
1784        //  allow_splash_only_nodes
1785        $title = _("Splash-only nodes");
1786        $help = _("Are nodes allowed to be set as splash-only (no login)?");
1787        $data = InterfaceElements::generateInputCheckbox("network_" . $this->getId() . "_allow_splash_only_nodes", "", _("Yes"), $this->getSplashOnlyNodesAllowed(), "network_allow_splash_only_nodes_radio");
1788        $html_network_node_properties[] = InterfaceElements::generateAdminSectionContainer("network_allow_splash_only_nodes", $title, $data, $help);
1789
1790        //  allow_custom_portal_redirect
1791        $title = _("Portal page redirection");
1792        $help = _("Are nodes allowed to redirect users to an arbitrary web page instead of the portal?");
1793        $data = InterfaceElements::generateInputCheckbox("network_" . $this->getId() . "_allow_custom_portal_redirect", "", _("Yes"), $this->getCustomPortalRedirectAllowed(), "network_allow_custom_portal_redirect_radio");
1794        $html_network_node_properties[] = InterfaceElements::generateAdminSectionContainer("network_allow_custom_portal_redirect", $title, $data, $help);
1795
1796        //  allow_original_URL_redirect
1797        $title = _("Original URL redirection");
1798        $help = _("Are nodes allowed to redirect users to the web page they originally requested instead of the portal?");
1799        $data = InterfaceElements::generateInputCheckbox("network_" . $this->getId() . "_allow_original_URL_redirect", "", _("Yes"), $this->getPortalOriginalUrlAllowed(), "network_allow_original_URL_redirect_radio");
1800        $html_network_node_properties[] = InterfaceElements::generateAdminSectionContainer("network_allow_original_URL_redirect", $title, $data, $help);   
1801
1802        // Build section
1803        $html .= InterfaceElements::generateAdminSectionContainer("network_node_properties", _("Network's node properties"), implode(null, $html_network_node_properties));
1804
1805        /*
1806         * Network's user verification
1807         */
1808        $html_network_user_verification = array();
1809
1810        //  validation_grace_time
1811        $title = _("Validation grace period");
1812        $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.");
1813        $data = InterfaceElements::generateInputText("network_" . $this->getId() . "_validation_grace_time", $this->getValidationGraceTime(), "network_validation_grace_time_input");
1814        $html_network_user_verification[] = InterfaceElements::generateAdminSectionContainer("network_validation_grace_time", $title, $data, $help);
1815
1816        //  validation_email_from_address
1817        $title = _("This will be the from address of the validation email");
1818        $data = InterfaceElements::generateInputText("network_" . $this->getId() . "_validation_email_from_address", $this->getValidationEmailFromAddress(), "network_validation_email_from_address_input");
1819        $html_network_user_verification[] = InterfaceElements::generateAdminSectionContainer("network_validation_email_from_address", $title, $data);
1820
1821        //  allow_multiple_login
1822        $title = _("Multiple connections");
1823        $help = _("Can an account be connected more than once at the same time?");
1824        $data = InterfaceElements::generateInputCheckbox("network_" . $this->getId() . "_allow_multiple_login", "", _("Yes"), $this->getMultipleLoginAllowed(), "network_allow_multiple_login_radio");
1825        $html_network_user_verification[] = InterfaceElements::generateAdminSectionContainer("network_allow_multiple_login", $title, $data, $help);
1826       
1827         
1828        //  network_authenticator_params
1829        $title = _("Case sensitivity");
1830        $help = _("Are usernames case sensitive?");
1831        $data = InterfaceElements::generateInputCheckbox("network_" . $this->getId() . "_usernames_case_sensitive","", _("Yes"), $this->getUsernamesCaseSensitive(), "network_usernames_case_sensitive");
1832        $html_network_user_verification[] = InterfaceElements::generateAdminSectionContainer("network_usernames_case_sensitive", $title, $data, $help);
1833
1834        // Build section
1835        $html .= InterfaceElements::generateAdminSectionContainer("network_user_verification", _("Network's user verification"), implode(null, $html_network_user_verification));
1836
1837        /*
1838         * Dynamic abuse control
1839         */
1840        $html_dynamic_abuse_control = array();
1841        $permArray=null;
1842        $permArray[]=array(Permission::P('NETWORK_PERM_EDIT_DYNAMIC_ABUSE_CONTROL'), $this);
1843        if (Security::hasAnyPermission($permArray)) {
1844            //  connection_limit_window
1845            $title = _("Abuse control window");
1846            $help = _("The length of the window during which the user must not have exceeded the limits below.  Any valid postgresql interval expression is acceptable, typically '1 month' '1 week'.  A user who exceeds the limits will be denied access until his usage falls below the limits.");
1847            $data = InterfaceElements::generateInputText("network_" . $this->getId() . "_connection_limit_window", $this->getConnectionLimitWindow(), "network_connection_limit_window_input");
1848            $html_dynamic_abuse_control[] = InterfaceElements::generateAdminSectionContainer("network_connection_limit_window", $title, $data, $help);
1849
1850            //  connection_limit_network_max_total_bytes
1851            $title = _("Network max total bytes transfered");
1852            $help = _("Maximum data transfer during the abuse control window");
1853            $data = InterfaceElements::generateInputText("network_" . $this->getId() . "_connection_limit_network_max_total_bytes", $this->getConnectionLimitNetworkMaxTotalBytes(), "network_connection_limit_network_max_total_bytes");
1854            $html_dynamic_abuse_control[] = InterfaceElements::generateAdminSectionContainer("network_connection_limit_network_max_total_bytes", $title, $data, $help);
1855
1856            //  connection_limit_network_max_usage_duration
1857            $title = _("Network max connection duration");
1858            $help = _("Maximum connection duration during the abuse control window.  Any valid postgresql interval expression is acceptable, such as hh:mm:ss");
1859            $data = InterfaceElements::generateInputText("network_" . $this->getId() . "_connection_limit_network_max_usage_duration", $this->getConnectionLimitNetworkMaxDuration(), "network_connection_limit_network_max_usage_duration");
1860            $html_dynamic_abuse_control[] = InterfaceElements::generateAdminSectionContainer("network_connection_limit_network_max_usage_duration", $title, $data, $help);
1861
1862            //  connection_limit_node_max_total_bytes
1863            $title = _("Node max total bytes transfered");
1864            $help = _("Maximum data transfer during the abuse control window");
1865            $data = InterfaceElements::generateInputText("network_" . $this->getId() . "_connection_limit_node_max_total_bytes", $this->getConnectionLimitNodeMaxTotalBytes(), "network_connection_limit_node_max_total_bytes");
1866            $html_dynamic_abuse_control[] = InterfaceElements::generateAdminSectionContainer("network_connection_limit_node_max_total_bytes", $title, $data, $help);
1867
1868            //  connection_limit_node_max_usage_duration
1869            $title = _("Node max connection duration");
1870            $help = _("Maximum connection duration during the abuse control window.  Any valid postgresql interval expression is acceptable, such as hh:mm:ss");
1871            $data = InterfaceElements::generateInputText("network_" . $this->getId() . "_connection_limit_node_max_usage_duration", $this->getConnectionLimitNodeMaxDuration(), "network_connection_limit_node_max_usage_duration");
1872            $html_dynamic_abuse_control[] = InterfaceElements::generateAdminSectionContainer("network_connection_limit_node_max_usage_duration", $title, $data, $help);
1873        }
1874        else{
1875            $html_dynamic_abuse_control[] = _("You do not have access to edit these options");
1876        }
1877        // Build section
1878        $html .= InterfaceElements::generateAdminSectionContainer("network_user_verification", _("Dynamic abuse control"), implode(null, $html_dynamic_abuse_control));
1879
1880        /*
1881         * Access management
1882         */
1883        $html_access_rights = array();
1884
1885        /*
1886         * Access rights
1887         */
1888        if (true) {
1889            require_once('classes/Stakeholder.php');
1890            $html_access_rights = Stakeholder::getAssignStakeholdersUI($this);
1891            $html .= InterfaceElements::generateAdminSectionContainer("access_rights", _("Access rights"), $html_access_rights);
1892        }
1893        /*
1894         * Network GIS data
1895         */
1896        if (defined('GMAPS_HOTSPOTS_MAP_ENABLED') && GMAPS_HOTSPOTS_MAP_ENABLED == true) {
1897            $html_network_gis_data = array();
1898
1899            $gis_point = $this->getGisLocation();
1900            $gis_lat_name = "network_" . $this->getId() . "_gis_latitude";
1901            $gis_lat_value = htmlspecialchars($gis_point->getLatitude(), ENT_QUOTES);
1902            $gis_long_name = "network_" . $this->getId() . "_gis_longitude";
1903            $gis_long_value = htmlspecialchars($gis_point->getLongitude(), ENT_QUOTES);
1904            $gis_alt_name = "network_" . $this->getId() . "_gis_altitude";
1905            $gis_alt_value = htmlspecialchars($gis_point->getAltitude(), ENT_QUOTES);
1906
1907            $html_network_gis_data[] = '<p>'._("Note that to be valid, all 3 values must be present.")."</p>\n";
1908            $title = _("Latitude");
1909            $help = _("Center latitude for the area covered by your wireless network");
1910            $data = InterfaceElements::generateInputText($gis_lat_name, $gis_lat_value, "network_gis_latitude_input");
1911            $html_network_gis_data[] = InterfaceElements::generateAdminSectionContainer("network_gis_latitude", $title, $data, $help);
1912
1913            $title = _("Longitude");
1914            $help = _("Center longitude for the area covered by your wireless network");
1915            $data = InterfaceElements::generateInputText($gis_long_name, $gis_long_value, "network_gis_longitude_input");
1916            $html_network_gis_data[] = InterfaceElements::generateAdminSectionContainer("network_gis_longitude", $title, $data, $help);
1917
1918            $title = _("Zoomlevel");
1919            $help = _("Zoomlevel of the Google Map.  12 is a typical value.");
1920            $data = InterfaceElements::generateInputText($gis_alt_name, $gis_alt_value, "network_gis_altitude_input");
1921            $html_network_gis_data[] = InterfaceElements::generateAdminSectionContainer("network_gis_altitude", $title, $data, $help);
1922
1923            $title = _("Map type");
1924            $help = _("Default Google Map type for your the area of your wireless network");
1925            $data = $this->getSelectGisMapType("network_" . $this->getId() . "_gmaps_map_type", $this->getGisMapType());
1926            $html_network_gis_data[] = InterfaceElements::generateAdminSectionContainer("network_gmaps_map_type", $title, $data, $help);
1927
1928            // Build section
1929            $html .= InterfaceElements::generateAdminSectionContainer("network_gis_data", _("GIS data"), implode(null, $html_network_gis_data));
1930        }
1931
1932        // Profile templates
1933        $title = _("Network profile templates");
1934        $name = "network_".$this->_id."_profile_templates";
1935        $data = ProfileTemplate::getLinkedProfileTemplateUI($name, "network_has_profile_templates", "network_id", $this->_id);
1936        $html .= InterfaceElements::generateAdminSectionContainer("network_profile_templates", $title, $data);
1937       
1938        // objects hierarchy
1939        if (!is_null($this->_hotspotGraphElement))
1940            $html .= $this->_hotspotGraphElement->getGraphAdminUI($this);
1941
1942        $html .= "</ul>\n";
1943        $html .= "</fieldset>";
1944
1945        return $html;
1946    }
1947
1948    /**
1949     * Process admin interface of this object.
1950     *
1951     * @return void
1952     *
1953     * @access public
1954     */
1955    public function processAdminUI()
1956    {
1957        Security::requirePermission(Permission::P('NETWORK_PERM_EDIT_NETWORK_CONFIG'), $this);
1958
1959        // Content management
1960        if (!is_null($this->_hotspotGraphElement))
1961            $this->_hotspotGraphElement->processContentAdminUI();
1962        /* $name = "network_".$this->_id."_content";
1963        Content :: processLinkedContentUI($name, 'network_has_content', 'network_id', $this->_id);*/
1964
1965        // name
1966        $name = "network_".$this->getId()."_name";
1967        $this->setName($_REQUEST[$name]);
1968
1969        // creation_date
1970        $name = "network_".$this->getId()."_creation_date";
1971        $this->setCreationDate($_REQUEST[$name]);
1972
1973        // homepage_url
1974        $name = "network_".$this->getId()."_homepage_url";
1975        $this->setWebSiteUrl($_REQUEST[$name]);
1976
1977        // tech_support_email
1978        $name = "network_".$this->getId()."_tech_support_email";
1979        $this->setTechSupportEmail($_REQUEST[$name]);
1980
1981        //  network_authenticator_class
1982        $name = "network_".$this->getId()."_network_authenticator_class";
1983        $this->setAuthenticatorClassName($_REQUEST[$name]);
1984
1985        //  network_authenticator_params
1986        $name = "network_".$this->getId()."_network_authenticator_params";
1987        $this->setAuthenticatorConstructorParams($_REQUEST[$name]);
1988
1989        //  is_default_network
1990        $name = "network_".$this->getId()."_is_default_network";
1991        if (!empty ($_REQUEST[$name]) && $_REQUEST[$name] == 'on')
1992        $this->setAsDefaultNetwork();
1993
1994        //  validation_grace_time
1995        $name = "network_".$this->getId()."_validation_grace_time";
1996        $this->setValidationGraceTime($_REQUEST[$name]);
1997
1998        //  validation_email_from_address
1999        $name = "network_".$this->getId()."_validation_email_from_address";
2000        $this->setValidationEmailFromAddress($_REQUEST[$name]);
2001       
2002        $name = "network_" . $this->getId() . "_usernames_case_sensitive";
2003        $this->setUsernamesCaseSensitive(empty ($_REQUEST[$name]) ? false : true);
2004
2005        //  theme_pack
2006        $name = "network_".$this->getId()."_theme_pack";
2007        if (!empty ($_REQUEST[$name])) {
2008            $theme_pack = ThemePack::getObject($_REQUEST[$name]);
2009        }
2010        else {
2011            $theme_pack = null;
2012        }
2013        $this->setThemePack($theme_pack);
2014
2015        //  allow_multiple_login
2016        $name = "network_".$this->getId()."_allow_multiple_login";
2017        $this->setMultipleLoginAllowed(empty ($_REQUEST[$name]) ? false : true);
2018
2019        //  allow_splash_only_nodes
2020        $name = "network_".$this->getId()."_allow_splash_only_nodes";
2021        $this->setSplashOnlyNodesAllowed(empty ($_REQUEST[$name]) ? false : true);
2022
2023        //  allow_custom_portal_redirect
2024        $name = "network_".$this->getId()."_allow_custom_portal_redirect";
2025        $this->setCustomPortalRedirectAllowed(empty ($_REQUEST[$name]) ? false : true);
2026
2027        //  'allow_original_URL_redirect
2028        $name = "network_".$this->getId()."_allow_original_URL_redirect";
2029        $this->setPortalOriginalUrlAllowed(empty ($_REQUEST[$name]) ? false : true);
2030
2031        /*
2032         * Dynamic abuse control
2033         */
2034        $html_dynamic_abuse_control = array();
2035        $permArray=null;
2036        $permArray[]=array(Permission::P('NETWORK_PERM_EDIT_DYNAMIC_ABUSE_CONTROL'), $this);
2037        if (Security::hasAnyPermission($permArray)) {
2038            //  connection_limit_window
2039            $name = "network_" . $this->getId() . "_connection_limit_window";
2040            $this->setConnectionLimitWindow($_REQUEST[$name]);
2041
2042            //  connection_limit_network_max_total_bytes
2043            $name = "network_" . $this->getId() . "_connection_limit_network_max_total_bytes";
2044            $this->setConnectionLimitNetworkMaxTotalBytes($_REQUEST[$name]);
2045
2046            //  connection_limit_network_max_usage_duration
2047            $name = "network_" . $this->getId() . "_connection_limit_network_max_usage_duration";
2048            $this->setConnectionLimitNetworkMaxDuration($_REQUEST[$name]);
2049
2050            //  connection_limit_node_max_total_bytes
2051            $name = "network_" . $this->getId() . "_connection_limit_node_max_total_bytes";
2052            $this->setConnectionLimitNodeMaxTotalBytes($_REQUEST[$name]);
2053
2054            //  connection_limit_node_max_usage_duration
2055            $name = "network_" . $this->getId() . "_connection_limit_node_max_usage_duration";
2056            $this->setConnectionLimitNodeMaxDuration($_REQUEST[$name]);
2057        }
2058         
2059        // Access rights
2060        require_once('classes/Stakeholder.php');
2061        Stakeholder::processAssignStakeholdersUI($this, $errMsg);
2062        if(!empty($errMsg)) {
2063            echo $errMsg;
2064        }
2065
2066        // GIS data
2067        if (defined('GMAPS_HOTSPOTS_MAP_ENABLED') && GMAPS_HOTSPOTS_MAP_ENABLED == true) {
2068            $gis_lat_name = "network_".$this->getId()."_gis_latitude";
2069            $gis_long_name = "network_".$this->getId()."_gis_longitude";
2070            $gis_alt_name = "network_".$this->getId()."_gis_altitude";
2071            $this->setGisLocation(new GisPoint($_REQUEST[$gis_lat_name], $_REQUEST[$gis_long_name], $_REQUEST[$gis_alt_name]));
2072
2073            $name = "network_".$this->getId()."_gmaps_map_type";
2074            $this->setGisMapType($_REQUEST[$name]);
2075        }
2076
2077        // Profile templates
2078        $name = "network_".$this->_id."_profile_templates";
2079        ProfileTemplate :: processLinkedProfileTemplateUI($name, 'network_has_profile_templates', 'network_id', $this->_id);
2080       
2081        if (!is_null($this->_hotspotGraphElement))
2082            $this->_hotspotGraphElement->processGraphAdminUI($errMsg, $this);
2083        if(!empty($errMsg)) {
2084            echo $errMsg;
2085            $errMsg = null;
2086        }
2087
2088        // Node creation
2089        $new_node = Node :: processCreateNewObjectUI();
2090        if ($new_node) {
2091            $url = GENERIC_OBJECT_ADMIN_ABS_HREF."?".http_build_query(array ("object_class" => "Node", "action" => "edit", "object_id" => $new_node->getId()));
2092            header("Location: {$url}");
2093        }
2094    }
2095
2096    /**
2097     * Add network-wide content to this network
2098     *
2099     * @param object Content object
2100     *
2101     * @return void
2102     *
2103     * @access public
2104     */
2105    public function addContent(Content $content)
2106    {
2107        $db = AbstractDb::getObject();
2108
2109        $content_id = $db->escapeString($content->getId());
2110        $sql = "INSERT INTO network_has_content (network_id, content_id) VALUES ('$this->_id','$content_id')";
2111        $db->execSqlUpdate($sql, false);
2112    }
2113
2114    /**
2115     * Remove network-wide content from this network
2116     *
2117     * @param object Content object
2118     *
2119     * @return void
2120     *
2121     * @access public
2122     */
2123    public function removeContent(Content $content)
2124    {
2125        $db = AbstractDb::getObject();
2126
2127        $content_id = $db->escapeString($content->getId());
2128        $sql = "DELETE FROM network_has_content WHERE network_id='$this->_id' AND content_id='$content_id'";
2129        $db->execSqlUpdate($sql, false);
2130    }
2131
2132
2133    /**
2134     * Add a profile template to this network
2135     *
2136     * @param object ProfileTemplate object
2137     *
2138     * @return void
2139     *
2140     * @access public
2141     */
2142    public function addProfileTemplate(ProfileTemplate $profile_template)
2143    {
2144        $db = AbstractDb::getObject();
2145
2146        $profile_template_id = $db->escapeString($profile_template->getId());
2147        $sql = "INSERT INTO network_has_profile_templates (network_id, profile_template_id) VALUES ('$this->_id','$profile_template_id')";
2148        $db->execSqlUpdate($sql, false);
2149    }
2150
2151    /**
2152     * Remove a profile template to this network
2153     *
2154     * @param object ProfileTemplate object
2155     *
2156     * @return void
2157     *
2158     * @access public
2159     */
2160    public function removeProfileTemplate(ProfileTemplate $profile_template)
2161    {
2162        $db = AbstractDb::getObject();
2163
2164        $profile_template_id = $db->escapeString($profile_template->getId());
2165        $sql = "DELETE FROM network_has_profile_templates WHERE network_id='$this->_id' AND profile_template_id='$profile_template_id'";
2166        $db->execSqlUpdate($sql, false);
2167    }
2168
2169    /**Get an array of all ProfileTemplates linked to this network
2170     * @return an array of ProfileTemplates or an empty arrray */
2171    function getAllProfileTemplates() {
2172        $db = AbstractDb::getObject();
2173        $retval = array ();
2174        $profile_template_rows = null;
2175        $sql = "SELECT profile_template_id FROM network_has_profile_templates WHERE network_id='$this->_id'";
2176        $db->execSql($sql, $profile_template_rows, false);
2177        if ($profile_template_rows != null) {
2178            foreach ($profile_template_rows as $profile_template_row) {
2179                $retval[] = ProfileTemplate :: getObject($profile_template_row['profile_template_id']);
2180            }
2181        }
2182        return $retval;
2183    }
2184
2185    /**
2186     * Delete this Object form the it's storage mechanism
2187     *
2188     * @param string &$errmsg Returns an explanation of the error on failure
2189     *
2190     * @return bool true on success, false on failure or access denied
2191     *
2192     * @access public
2193     */
2194    public function delete(& $errmsg)
2195    {
2196        // Init values
2197        $retval = false;
2198        Security::requirePermission(Permission::P('NETWORK_PERM_DELETE_NETWORK'), $this);
2199        if ($this->isDefaultNetwork() === true) {
2200            $errmsg = _('Cannot delete default network, create another one and select it before you remove this one.');
2201        } else {
2202            $db = AbstractDb::getObject();
2203            $id = $db->escapeString($this->getId());
2204            if (!$db->execSqlUpdate("DELETE FROM networks WHERE network_id='{$id}'", false)) {
2205                $errmsg = _('Could not delete network!');
2206            } else {
2207                $retval = true;
2208            }
2209        }
2210
2211
2212        return $retval;
2213    }
2214    /**
2215     * Reloads the object from the database.
2216     *
2217     * Should normally be called after a set operation
2218     *
2219     * @return void
2220     *
2221     * @access protected
2222     */
2223    protected function refresh()
2224    {
2225        $this->__construct($this->_id);
2226    }
2227
2228    /** Menu hook function */
2229    static public function hookMenu() {
2230        $items = array();
2231        if($networks = Security::getObjectsWithPermission(Permission::P('NETWORK_PERM_EDIT_NETWORK_CONFIG'))) {
2232            foreach ($networks as $networkId => $network) {
2233                $items[] = array('path' => 'network/network_'.$networkId.'edit',
2234                'title' => sprintf(_("Edit %s"), $network->getName()),
2235                'url' => BASE_URL_PATH.htmlspecialchars("admin/generic_object_admin.php?object_class=Network&action=edit&object_id=$networkId")
2236                );
2237            }
2238        }
2239        if(Security::hasPermission(Permission::P('SERVER_PERM_ADD_NEW_NETWORK'), Server::getServer())){
2240            $items[] = array('path' => 'network/network_add_new',
2241                'title' => sprintf(_("Add a new network on this server")),
2242                'url' => BASE_URL_PATH.htmlspecialchars("admin/generic_object_admin.php?object_class=Network&action=new_ui")
2243            );
2244        }
2245        $items[] = array('path' => 'network',
2246                'title' => _('Network administration'),
2247                'type' => MENU_ITEM_GROUPING);
2248        return $items;
2249    }
2250
2251    /**
2252     * Assigns values about network to be processed by the Smarty engine.
2253     *
2254     * @param object $smarty Smarty object
2255     * @param object $net    Network object
2256     *
2257     * @return void
2258     */
2259    public static function assignSmartyValues($smarty, $net = null)
2260    {
2261        if (!$net) {
2262            $net = Network::getCurrentNetwork();
2263        }
2264
2265        // Set network details
2266        $smarty->assign('networkName', $net ? $net->getName() : '');
2267        $smarty->assign('networkWebSiteURL', $net ? $net->getWebSiteURL() : '');
2268        // Set networks usage information
2269        $smarty->assign('networkNumOnlineUsers', $net ? $net->getNumOnlineUsers() : 0);
2270
2271        // Set networks node information
2272        $smarty->assign('networkNumDeployedNodes', $net ? $net->getNumDeployedNodes() : 0);
2273        $smarty->assign('networkNumOnlineNodes', $net ? $net->getNumOnlineNodes() : 0);
2274        $smarty->assign('networkNumNonMonitoredNodes', $net ? $net->getNumOnlineNodes(true) : 0);
2275    }
2276}
2277
2278/*
2279 * Local variables:
2280 * tab-width: 4
2281 * c-basic-offset: 4
2282 * c-hanging-comment-ender-p: nil
2283 * End:
2284 */
Note: See TracBrowser for help on using the browser.